PageRenderTime 38ms CodeModel.GetById 15ms app.highlight 17ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/phoenix/doc/html/phoenix/examples/extending_actors.html

http://hadesmem.googlecode.com/
HTML | 320 lines | 309 code | 11 blank | 0 comment | 0 complexity | 6a19aa79c187a324a65107c674a04195 MD5 | raw file
  1<html>
  2<head>
  3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4<title>Extending Actors</title>
  5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
  6<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
  7<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Phoenix 3.0">
  8<link rel="up" href="../examples.html" title="Advanced Examples">
  9<link rel="prev" href="../examples.html" title="Advanced Examples">
 10<link rel="next" href="adding_an_expression.html" title="Adding an expression">
 11</head>
 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
 13<table cellpadding="2" width="100%"><tr>
 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
 15<td align="center"><a href="../../../../../../index.html">Home</a></td>
 16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
 19<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
 20</tr></table>
 21<hr>
 22<div class="spirit-nav">
 23<a accesskey="p" href="../examples.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="adding_an_expression.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
 24</div>
 25<div class="section">
 26<div class="titlepage"><div><div><h3 class="title">
 27<a name="phoenix.examples.extending_actors"></a><a class="link" href="extending_actors.html" title="Extending Actors">Extending Actors</a>
 28</h3></div></div></div>
 29<p>
 30        <a class="link" href="../inside/actor.html" title="Actors in Detail">Actors</a> are one of the main parts
 31        of the library, and one of the many customization points. The default actor
 32        implementation provides several operator() overloads which deal with the
 33        evaluation of expressions.
 34      </p>
 35<p>
 36        For some use cases this might not be enough. For convenience it is thinkable
 37        to provide custom member functions which generate new expressions. An example
 38        is the <a class="link" href="../modules/statement/___if_else_____statement.html" title="if_else_ Statement">if_else_
 39Statement</a>
 40        which provides an additional else member for generating a lazy if-else expression.
 41        With this the actual Phoenix expression becomes more expressive.
 42      </p>
 43<p>
 44        Another scenario is to give actors the semantics of a certain well known
 45        interface or concept. This tutorial like section will provide information
 46        on how to implement a custom actor which is usable as if it were a <a href="http://www.sgi.com/tech/stl/Container.html" target="_top">STL Container</a>.
 47      </p>
 48<a name="phoenix.examples.extending_actors.requirements"></a><h5>
 49<a name="id859806"></a>
 50        <a class="link" href="extending_actors.html#phoenix.examples.extending_actors.requirements">Requirements</a>
 51      </h5>
 52<p>
 53        Let's repeat what we want to have:
 54      </p>
 55<div class="informaltable"><table class="table">
 56<colgroup>
 57<col>
 58<col>
 59</colgroup>
 60<thead><tr>
 61<th>
 62                <p>
 63                  Expression
 64                </p>
 65              </th>
 66<th>
 67                <p>
 68                  Semantics
 69                </p>
 70              </th>
 71</tr></thead>
 72<tbody>
 73<tr>
 74<td>
 75                <p>
 76                  <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()</span></code>
 77                </p>
 78              </td>
 79<td>
 80                <p>
 81                  Returns an iterator pointing to the first element in the container.
 82                </p>
 83              </td>
 84</tr>
 85<tr>
 86<td>
 87                <p>
 88                  <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span></code>
 89                </p>
 90              </td>
 91<td>
 92                <p>
 93                  Returns an iterator pointing one past the last element in the container.
 94                </p>
 95              </td>
 96</tr>
 97<tr>
 98<td>
 99                <p>
100                  <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span></code>
101                </p>
102              </td>
103<td>
104                <p>
105                  Returns the size of the container, that is, its number of elements.
106                </p>
107              </td>
108</tr>
109<tr>
110<td>
111                <p>
112                  <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">max_size</span><span class="special">()</span></code>
113                </p>
114              </td>
115<td>
116                <p>
117                  Returns the largest size that this container can ever have.
118                </p>
119              </td>
120</tr>
121<tr>
122<td>
123                <p>
124                  <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">empty</span><span class="special">()</span></code>
125                </p>
126              </td>
127<td>
128                <p>
129                  Equivalent to a.size() == 0. (But possibly faster.)
130                </p>
131              </td>
132</tr>
133<tr>
134<td>
135                <p>
136                  <code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">b</span><span class="special">)</span></code>
137                </p>
138              </td>
139<td>
140                <p>
141                  Equivalent to swap(a,b)
142                </p>
143              </td>
144</tr>
145</tbody>
146</table></div>
147<p>
148        Additionally, we want all the operator() overloads of the regular actor.
149      </p>
150<a name="phoenix.examples.extending_actors.defining_the_actor"></a><h5>
151<a name="id860119"></a>
152        <a class="link" href="extending_actors.html#phoenix.examples.extending_actors.defining_the_actor">Defining
153        the actor</a>
154      </h5>
155<p>
156        The first version of our <code class="computeroutput"><span class="identifier">container_actor</span></code>
157        interface will show the general principle. This will be continually extended.
158        For the sake of simplicity, every member function generator will return
159        <a class="link" href="../modules/core/nothing.html" title="Nothing"><code class="computeroutput"><span class="identifier">nothing</span></code></a>
160        at first.
161      </p>
162<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
163<span class="keyword">struct</span> <span class="identifier">container_actor</span>
164	<span class="special">:</span> <span class="identifier">actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span>
165<span class="special">{</span>
166	<span class="keyword">typedef</span> <span class="identifier">actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span> <span class="identifier">base_type</span><span class="special">;</span>
167	<span class="keyword">typedef</span> <span class="identifier">container_actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span> <span class="identifier">that_type</span><span class="special">;</span>
168	
169	<span class="identifier">container_actor</span><span class="special">(</span> <span class="identifier">base_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">base</span> <span class="special">)</span>
170		<span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span> <span class="identifier">base</span> <span class="special">)</span> <span class="special">{}</span>
171
172	<span class="identifier">expression</span><span class="special">::</span><span class="identifier">null</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">void_</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">nothing</span><span class="special">;</span> <span class="special">}</span>
173	<span class="identifier">expression</span><span class="special">::</span><span class="identifier">null</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">void_</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">nothing</span><span class="special">;</span> <span class="special">}</span>
174	<span class="identifier">expression</span><span class="special">::</span><span class="identifier">null</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">void_</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">nothing</span><span class="special">;</span> <span class="special">}</span>
175	<span class="identifier">expression</span><span class="special">::</span><span class="identifier">null</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">void_</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">max_size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">nothing</span><span class="special">;</span> <span class="special">}</span>
176	<span class="identifier">expression</span><span class="special">::</span><span class="identifier">null</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">void_</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">nothing</span><span class="special">;</span> <span class="special">}</span>
177
178	<span class="comment">// Note that swap is the only function needing another container.
179</span>	<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">&gt;</span>
180	<span class="identifier">expression</span><span class="special">::</span><span class="identifier">null</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">void_</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">actor</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">nothing</span><span class="special">;</span> <span class="special">}</span>
181<span class="special">};</span>
182</pre>
183<a name="phoenix.examples.extending_actors.using_the_actor"></a><h5>
184<a name="id861004"></a>
185        <a class="link" href="extending_actors.html#phoenix.examples.extending_actors.using_the_actor">Using the
186        actor</a>
187      </h5>
188<p>
189        Although the member functions do nothing right now, we want to test if we
190        can use our new actor.
191      </p>
192<p>
193        First, lets create a generator which wraps the <code class="computeroutput"><span class="identifier">container_actor</span></code>
194        around any other expression:
195      </p>
196<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
197<span class="identifier">container_actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span> <span class="keyword">const</span>
198<span class="identifier">container</span><span class="special">(</span> <span class="identifier">actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">expr</span> <span class="special">)</span>
199<span class="special">{</span>
200    <span class="keyword">return</span> <span class="identifier">expr</span><span class="special">;</span>
201<span class="special">}</span>
202</pre>
203<p>
204        Now let's test this:
205      </p>
206<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">;</span>
207<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
208<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
209<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
210<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">3</span><span class="special">);</span>
211
212<span class="special">(</span><span class="identifier">container</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">).</span><span class="identifier">size</span><span class="special">())(</span><span class="identifier">v</span><span class="special">);</span>
213</pre>
214<p>
215        Granted, this is not really elegant and not very practical (we could have
216        just used phoenix::begin(v) from the <a class="link" href="../modules/stl/algorithm.html" title="Algorithm">Phoenix
217        algorithm module</a>, but we can do better.
218      </p>
219<p>
220        Let's have an <a class="link" href="../modules/core/arguments.html" title="Arguments">argument placeholder</a>
221        which is usable as if it was a STL container:
222      </p>
223<pre class="programlisting"><span class="identifier">container_actor</span><span class="special">&lt;</span><span class="identifier">expression</span><span class="special">::</span><span class="identifier">argument</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">con1</span><span class="special">;</span>
224<span class="comment">// and so on ...
225</span></pre>
226<p>
227        The above example can be rewritten as:
228      </p>
229<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">;</span>
230<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
231<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
232<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
233<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">3</span><span class="special">);</span>
234
235<span class="special">(</span><span class="identifier">con1</span><span class="special">.</span><span class="identifier">size</span><span class="special">())(</span><span class="identifier">v</span><span class="special">);</span>
236</pre>
237<p>
238        Wow, that was easy!
239      </p>
240<a name="phoenix.examples.extending_actors.adding_life_to_the_actor"></a><h5>
241<a name="id861671"></a>
242        <a class="link" href="extending_actors.html#phoenix.examples.extending_actors.adding_life_to_the_actor">Adding
243        life to the actor</a>
244      </h5>
245<p>
246        This one will be even easier!
247      </p>
248<p>
249        First, we define a <a class="link" href="../modules/function.html" title="Function">lazy function</a>
250        which evaluates the expression we want to implement. Following is the implementation
251        of the size function:
252      </p>
253<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">size_impl</span>
254<span class="special">{</span>
255	<span class="comment">// result_of protocol:
256</span>	<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sig</span><span class="special">&gt;</span>
257	<span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span>
258
259	<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">This</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">&gt;</span>
260	<span class="keyword">struct</span> <span class="identifier">result</span><span class="special">&lt;</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">Container</span><span class="special">)&gt;</span>
261	<span class="special">{</span>
262		<span class="comment">// Note, remove reference here, because Container can be anything
263</span>		<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">container_type</span><span class="special">;</span>
264
265		<span class="comment">// The result will be size_type
266</span>		<span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">container_type</span><span class="special">::</span><span class="identifier">size_type</span> <span class="identifier">type</span><span class="special">;</span>
267	<span class="special">};</span>
268
269	<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">&gt;</span>
270	<span class="keyword">typename</span> <span class="identifier">result</span><span class="special">&lt;</span><span class="identifier">size_impl</span><span class="special">(</span><span class="identifier">Container</span> <span class="keyword">const</span><span class="special">&amp;)&gt;::</span><span class="identifier">type</span>
271	<span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Container</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">container</span><span class="special">)</span> <span class="keyword">const</span>
272	<span class="special">{</span>
273		<span class="keyword">return</span> <span class="identifier">container</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span>
274	<span class="special">}</span>
275<span class="special">};</span>
276</pre>
277<p>
278        Good, this was the first part. The second part will be to implement the size
279        member function of <code class="computeroutput"><span class="identifier">container_actor</span></code>:
280      </p>
281<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
282<span class="keyword">struct</span> <span class="identifier">container_actor</span>
283	<span class="special">:</span> <span class="identifier">actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span>
284<span class="special">{</span>
285	<span class="keyword">typedef</span> <span class="identifier">actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span> <span class="identifier">base_type</span><span class="special">;</span>
286	<span class="keyword">typedef</span> <span class="identifier">container_actor</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;</span> <span class="identifier">that_type</span><span class="special">;</span>
287	
288	<span class="identifier">container_actor</span><span class="special">(</span> <span class="identifier">base_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">base</span> <span class="special">)</span>
289		<span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span> <span class="identifier">base</span> <span class="special">)</span> <span class="special">{}</span>
290
291	<span class="keyword">typename</span> <span class="identifier">expression</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="identifier">size_impl</span><span class="special">,</span> <span class="identifier">that_type</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span>
292	<span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span>
293	<span class="special">{</span>
294		<span class="identifier">function</span><span class="special">&lt;</span><span class="identifier">size_impl</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">size_impl</span><span class="special">();</span>
295		<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
296	<span class="special">}</span>
297
298	<span class="comment">// the rest ...
299</span><span class="special">};</span>
300</pre>
301<p>
302        It is left as an exercise to the user to implement the missing parts by reusing
303        functions from the <a class="link" href="../modules/stl/algorithm.html" title="Algorithm">Phoenix
304        Algorithm Module</a> (the impatient take a look here: <a href="../../../../example/container_actor.cpp" target="_top">container_actor.cpp</a>).
305      </p>
306</div>
307<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
308<td align="left"></td>
309<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005, 2010 Joel de Guzman, Dan Marsden, Thomas Heller<p>
310        Distributed under the Boost Software License, Version 1.0. (See accompanying
311        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
312      </p>
313</div></td>
314</tr></table>
315<hr>
316<div class="spirit-nav">
317<a accesskey="p" href="../examples.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../examples.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="adding_an_expression.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
318</div>
319</body>
320</html>