Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / fusion / doc / html / fusion / extension / ext_full.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>The Full Extension Mechanism</title>
5 <link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
7 <link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Fusion 2.2">
8 <link rel="up" href="../extension.html" title="Extension">
9 <link rel="prev" href="../extension.html" title="Extension">
10 <link rel="next" href="sequence_facade.html" title="Sequence Facade">
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="../extension.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../extension.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="sequence_facade.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="fusion.extension.ext_full"></a><a class="link" href="ext_full.html" title="The Full Extension Mechanism">The Full Extension Mechanism</a>
28 </h3></div></div></div>
29 <p>
30         The Fusion library is designed to be extensible, new sequences types can
31         easily be added. In fact, the library support for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>,
32         <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code> and <a href="http://www.boost.org/libs/mpl/index.html" target="_top">MPL</a>
33         sequences is entirely provided using the extension mechanism.
34       </p>
35 <p>
36         The process for adding a new sequence type to Fusion is:
37       </p>
38 <div class="orderedlist"><ol class="orderedlist" type="1">
39 <li class="listitem">
40             Enable the <a class="link" href="../notes.html#fusion.notes.tag_dispatching"><span class="emphasis"><em>tag
41             dispatching</em></span></a> mechanism used by Fusion for your sequence
42             type
43           </li>
44 <li class="listitem">
45             Design an iterator type for the sequence
46           </li>
47 <li class="listitem">
48             Provide specialized behaviour for the intrinsic operations of the new
49             Fusion sequence
50           </li>
51 </ol></div>
52 <h5>
53 <a name="fusion.extension.ext_full.h0"></a>
54         <span class="phrase"><a name="fusion.extension.ext_full.our_example"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.our_example">Our
55         example</a>
56       </h5>
57 <p>
58         In order to illustrate enabling a new sequence type for use with Fusion,
59         we are going to use the type:
60       </p>
61 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">example</span>
62 <span class="special">{</span>
63     <span class="keyword">struct</span> <span class="identifier">example_struct</span>
64     <span class="special">{</span>
65         <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span>
66         <span class="keyword">int</span> <span class="identifier">age</span><span class="special">;</span>
67         <span class="identifier">example_struct</span><span class="special">(</span>
68             <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">n</span><span class="special">,</span>
69             <span class="keyword">int</span> <span class="identifier">a</span><span class="special">)</span>
70             <span class="special">:</span> <span class="identifier">name</span><span class="special">(</span><span class="identifier">n</span><span class="special">),</span> <span class="identifier">age</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span>
71         <span class="special">{}</span>
72     <span class="special">};</span>
73 <span class="special">}</span>
74 </pre>
75 <p>
76         We are going to pretend that this type has been provided by a 3rd party library,
77         and therefore cannot be modified. We shall work through all the necessary
78         steps to enable <code class="computeroutput"><span class="identifier">example_struct</span></code>
79         to serve as an <a class="link" href="../sequence/concepts/associative_sequence.html" title="Associative Sequence">Associative
80         Sequence</a> as described in the <a class="link" href="../quick_start.html" title="Quick Start">Quick
81         Start</a> guide.
82       </p>
83 <h5>
84 <a name="fusion.extension.ext_full.h1"></a>
85         <span class="phrase"><a name="fusion.extension.ext_full.enabling_tag_dispatching"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.enabling_tag_dispatching">Enabling
86         Tag Dispatching</a>
87       </h5>
88 <p>
89         The Fusion extensibility mechanism uses <a class="link" href="../notes.html#fusion.notes.tag_dispatching"><span class="emphasis"><em>tag
90         dispatching</em></span></a> to call the correct code for a given sequence
91         type. In order to exploit the tag dispatching mechanism we must first declare
92         a new tag type for the mechanism to use. For example:
93       </p>
94 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">example</span> <span class="special">{</span>
95     <span class="keyword">struct</span> <span class="identifier">example_sequence_tag</span><span class="special">;</span> <span class="comment">// Only definition needed</span>
96 <span class="special">}</span>
97 </pre>
98 <p>
99         Next we need to enable the <code class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></code>
100         metafunction to return our newly chosen tag type for operations involving
101         our sequence. This is done by specializing <code class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></code>
102         for our sequence type.
103       </p>
104 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fusion</span><span class="special">/</span><span class="identifier">support</span><span class="special">/</span><span class="identifier">tag_of_fwd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
105 <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fusion</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">tag_of_fwd</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
106
107 <span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">fusion</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">traits</span> <span class="special">{</span>
108     <span class="keyword">template</span><span class="special">&lt;&gt;</span>
109     <span class="keyword">struct</span> <span class="identifier">tag_of</span><span class="special">&lt;</span><span class="identifier">example_struct</span><span class="special">&gt;</span>
110     <span class="special">{</span>
111         <span class="keyword">typedef</span> <span class="identifier">example</span><span class="special">::</span><span class="identifier">example_sequence_tag</span> <span class="identifier">type</span><span class="special">;</span>
112     <span class="special">};</span>
113 <span class="special">}}}</span>
114 </pre>
115 <p>
116         <code class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></code> also has a second template argument,
117         that can be used in conjuction with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span></code>
118         to provide tag support for groups of related types. This feature is not necessary
119         for our sequence, but for an example see the code in:
120       </p>
121 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fusion</span><span class="special">/</span><span class="identifier">adapted</span><span class="special">/</span><span class="identifier">array</span><span class="special">/</span><span class="identifier">tag_of</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
122 <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fusion</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">tag_of</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
123 </pre>
124 <h5>
125 <a name="fusion.extension.ext_full.h2"></a>
126         <span class="phrase"><a name="fusion.extension.ext_full.designing_a_suitable_iterator"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.designing_a_suitable_iterator">Designing
127         a suitable iterator</a>
128       </h5>
129 <p>
130         We need an iterator to describe positions, and provide access to the data
131         within our sequence. As it is straightforward to do, we are going to provide
132         a random access iterator in our example.
133       </p>
134 <p>
135         We will use a simple design, in which the 2 members of <code class="computeroutput"><span class="identifier">example_struct</span></code>
136         are given numbered indices, 0 for <code class="computeroutput"><span class="identifier">name</span></code>
137         and 1 for <code class="computeroutput"><span class="identifier">age</span></code> respectively.
138       </p>
139 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Struct</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">Pos</span><span class="special">&gt;</span>
140 <span class="keyword">struct</span> <span class="identifier">example_struct_iterator</span>
141     <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">iterator_base</span><span class="special">&lt;</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="identifier">Pos</span><span class="special">&gt;</span> <span class="special">&gt;</span>
142 <span class="special">{</span>
143     <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">Pos</span> <span class="special">&gt;=</span><span class="number">0</span> <span class="special">&amp;&amp;</span> <span class="identifier">Pos</span> <span class="special">&lt;</span> <span class="number">3</span><span class="special">);</span>
144     <span class="keyword">typedef</span> <span class="identifier">Struct</span> <span class="identifier">struct_type</span><span class="special">;</span>
145     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">int_</span><span class="special">&lt;</span><span class="identifier">Pos</span><span class="special">&gt;</span> <span class="identifier">index</span><span class="special">;</span>
146     <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">random_access_traversal_tag</span> <span class="identifier">category</span><span class="special">;</span>
147
148     <span class="identifier">example_struct_iterator</span><span class="special">(</span><span class="identifier">Struct</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">)</span>
149         <span class="special">:</span> <span class="identifier">struct_</span><span class="special">(</span><span class="identifier">str</span><span class="special">)</span> <span class="special">{}</span>
150
151     <span class="identifier">Struct</span><span class="special">&amp;</span> <span class="identifier">struct_</span><span class="special">;</span>
152 <span class="special">};</span>
153 </pre>
154 <p>
155         A quick summary of the details of our iterator:
156       </p>
157 <div class="orderedlist"><ol class="orderedlist" type="1">
158 <li class="listitem">
159             The iterator is parameterized by the type it is iterating over, and the
160             index of the current element.
161           </li>
162 <li class="listitem">
163             The typedefs <code class="computeroutput"><span class="identifier">struct_type</span></code>
164             and <code class="computeroutput"><span class="identifier">index</span></code> provide convenient
165             access to information we will need later in the implementation.
166           </li>
167 <li class="listitem">
168             The typedef <code class="computeroutput"><span class="identifier">category</span></code>
169             allows the <code class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><a class="link" href="../support/category_of.html" title="category_of"><code class="computeroutput"><span class="identifier">category_of</span></code></a></code>
170             metafunction to establish the traversal category of the iterator.
171           </li>
172 <li class="listitem">
173             The constructor stores a reference to the <code class="computeroutput"><span class="identifier">example_struct</span></code>
174             being iterated over.
175           </li>
176 </ol></div>
177 <p>
178         We also need to enable <a class="link" href="../notes.html#fusion.notes.tag_dispatching"><span class="emphasis"><em>tag
179         dispatching</em></span></a> for our iterator type, with another specialization
180         of <code class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></code>.
181       </p>
182 <p>
183         In isolation, the iterator implementation is pretty dry. Things should become
184         clearer as we add features to our implementation.
185       </p>
186 <h5>
187 <a name="fusion.extension.ext_full.h3"></a>
188         <span class="phrase"><a name="fusion.extension.ext_full.a_first_couple_of_instructive_features"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.a_first_couple_of_instructive_features">A
189         first couple of instructive features</a>
190       </h5>
191 <p>
192         To start with, we will get the <a class="link" href="../iterator/metafunctions/value_of.html" title="value_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></code></a> metafunction working. To
193         do this, we provide a specialization of the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">extension</span><span class="special">::</span><span class="identifier">value_of_impl</span></code>
194         template for our iterator's tag type.
195       </p>
196 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span>
197 <span class="keyword">struct</span> <span class="identifier">value_of_impl</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator_tag</span><span class="special">&gt;</span>
198 <span class="special">{</span>
199     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
200     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">;</span>
201
202     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Struct</span><span class="special">&gt;</span>
203     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="number">0</span><span class="special">&gt;</span> <span class="special">&gt;</span>
204     <span class="special">{</span>
205         <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">type</span><span class="special">;</span>
206     <span class="special">};</span>
207
208     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Struct</span><span class="special">&gt;</span>
209     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="special">&gt;</span>
210     <span class="special">{</span>
211         <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">type</span><span class="special">;</span>
212     <span class="special">};</span>
213 <span class="special">};</span>
214 </pre>
215 <p>
216         The implementation itself is pretty simple, it just uses 2 partial specializations
217         to provide the type of the 2 different members of <code class="computeroutput"><span class="identifier">example_struct</span></code>,
218         based on the index of the iterator.
219       </p>
220 <p>
221         To understand how <code class="computeroutput"><span class="identifier">value_of_impl</span></code>
222         is used by the library we will look at the implementation of <a class="link" href="../iterator/metafunctions/value_of.html" title="value_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></code></a>:
223       </p>
224 <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
225 <span class="keyword">struct</span> <span class="identifier">value_of</span>
226     <span class="special">:</span> <span class="identifier">extension</span><span class="special">::</span><span class="identifier">value_of_impl</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">tag_of</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;::</span>
227         <span class="keyword">template</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;</span>
228 <span class="special">{};</span>
229 </pre>
230 <p>
231         So <a class="link" href="../iterator/metafunctions/value_of.html" title="value_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></code></a>
232         uses <a class="link" href="../notes.html#fusion.notes.tag_dispatching"><span class="emphasis"><em>tag dispatching</em></span></a>
233         to select an <a href="http://www.boost.org/libs/mpl/doc/refmanual/metafunction-class.html" target="_top">MPL
234         Metafunction Class</a> to provide its functionality. You will notice
235         this pattern throughout the implementation of Fusion.
236       </p>
237 <p>
238         Ok, lets enable dereferencing of our iterator. In this case we must provide
239         a suitable specialization of <code class="computeroutput"><span class="identifier">deref_impl</span></code>.
240       </p>
241 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span>
242 <span class="keyword">struct</span> <span class="identifier">deref_impl</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator_tag</span><span class="special">&gt;</span>
243 <span class="special">{</span>
244     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
245     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">;</span>
246
247     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Struct</span><span class="special">&gt;</span>
248     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="number">0</span><span class="special">&gt;</span> <span class="special">&gt;</span>
249     <span class="special">{</span>
250         <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">if_</span><span class="special">&lt;</span>
251             <span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;&gt;::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span>
252
253         <span class="keyword">static</span> <span class="identifier">type</span>
254         <span class="identifier">call</span><span class="special">(</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="number">0</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">it</span><span class="special">)</span>
255         <span class="special">{</span>
256             <span class="keyword">return</span> <span class="identifier">it</span><span class="special">.</span><span class="identifier">struct_</span><span class="special">.</span><span class="identifier">name</span><span class="special">;</span>
257         <span class="special">}</span>
258     <span class="special">};</span>
259
260     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Struct</span><span class="special">&gt;</span>
261     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="special">&gt;</span>
262     <span class="special">{</span>
263         <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">if_</span><span class="special">&lt;</span>
264             <span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">&gt;,</span> <span class="keyword">int</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="keyword">int</span><span class="special">&amp;&gt;::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span>
265
266         <span class="keyword">static</span> <span class="identifier">type</span>
267         <span class="identifier">call</span><span class="special">(</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Struct</span><span class="special">,</span> <span class="number">1</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">it</span><span class="special">)</span>
268         <span class="special">{</span>
269                 <span class="keyword">return</span> <span class="identifier">it</span><span class="special">.</span><span class="identifier">struct_</span><span class="special">.</span><span class="identifier">age</span><span class="special">;</span>
270             <span class="special">}</span>
271         <span class="special">};</span>
272     <span class="special">};</span>
273 <span class="special">}</span>
274 </pre>
275 <p>
276         The use of <code class="computeroutput"><span class="identifier">deref_impl</span></code> is
277         very similar to that of <code class="computeroutput"><span class="identifier">value_of_impl</span></code>,
278         but it also provides some runtime functionality this time via the <code class="computeroutput"><span class="identifier">call</span></code> static member function. To see how
279         <code class="computeroutput"><span class="identifier">deref_impl</span></code> is used, lets
280         have a look at the implementation of <a class="link" href="../iterator/functions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">deref</span></code></a>:
281       </p>
282 <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">result_of</span>
283 <span class="special">{</span>
284     <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
285     <span class="keyword">struct</span> <a class="link" href="../iterator/functions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">deref</span></code></a>
286         <span class="special">:</span> <span class="identifier">extension</span><span class="special">::</span><span class="identifier">deref_impl</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">tag_of</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;::</span>
287             <span class="keyword">template</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;</span>
288     <span class="special">{};</span>
289 <span class="special">}</span>
290
291 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
292 <span class="keyword">typename</span> <span class="identifier">result_of</span><span class="special">::</span><span class="identifier">deref</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;::</span><span class="identifier">type</span>
293 <a class="link" href="../iterator/functions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">deref</span></code></a><span class="special">(</span><span class="identifier">Iterator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">i</span><span class="special">)</span>
294 <span class="special">{</span>
295     <span class="keyword">typedef</span> <span class="identifier">result_of</span><span class="special">::</span><span class="identifier">deref</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;</span> <span class="identifier">deref_meta</span><span class="special">;</span>
296     <span class="keyword">return</span> <span class="identifier">deref_meta</span><span class="special">::</span><span class="identifier">call</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
297 <span class="special">}</span>
298 </pre>
299 <p>
300         So again <a class="link" href="../iterator/metafunctions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">deref</span></code></a> uses <a class="link" href="../notes.html#fusion.notes.tag_dispatching"><span class="emphasis"><em>tag
301         dispatching</em></span></a> in exactly the same way as the <a class="link" href="../iterator/metafunctions/value_of.html" title="value_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></code></a> implementation. The runtime
302         functionality used by <a class="link" href="../iterator/functions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">deref</span></code></a> is provided by the <code class="computeroutput"><span class="identifier">call</span></code> static function of the selected <a href="http://www.boost.org/libs/mpl/doc/refmanual/metafunction-class.html" target="_top">MPL
303         Metafunction Class</a>.
304       </p>
305 <p>
306         The actual implementation of <code class="computeroutput"><span class="identifier">deref_impl</span></code>
307         is slightly more complex than that of <code class="computeroutput"><span class="identifier">value_of_impl</span></code>.
308         We also need to implement the <code class="computeroutput"><span class="identifier">call</span></code>
309         function, which returns a reference to the appropriate member of the underlying
310         sequence. We also require a little bit of metaprogramming to return <code class="computeroutput"><span class="keyword">const</span></code> references if the underlying sequence
311         is const.
312       </p>
313 <div class="note"><table border="0" summary="Note">
314 <tr>
315 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
316 <th align="left">Note</th>
317 </tr>
318 <tr><td align="left" valign="top"><p>
319           Although there is a fair amount of left to do to produce a fully fledged
320           Fusion sequence, <a class="link" href="../iterator/metafunctions/value_of.html" title="value_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></code></a> and <a class="link" href="../iterator/functions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">deref</span></code></a> illustrate all the signficant
321           concepts required. The remainder of the process is very repetitive, simply
322           requiring implementation of a suitable <code class="computeroutput"><span class="identifier">xxxx_impl</span></code>
323           for each feature <code class="computeroutput"><span class="identifier">xxxx</span></code>.
324         </p></td></tr>
325 </table></div>
326 <h5>
327 <a name="fusion.extension.ext_full.h4"></a>
328         <span class="phrase"><a name="fusion.extension.ext_full.implementing_the_remaining_iterator_functionality"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.implementing_the_remaining_iterator_functionality">Implementing
329         the remaining iterator functionality</a>
330       </h5>
331 <p>
332         Ok, now we have seen the way <a class="link" href="../iterator/metafunctions/value_of.html" title="value_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></code></a> and <a class="link" href="../iterator/functions/deref.html" title="deref"><code class="computeroutput"><span class="identifier">deref</span></code></a> work, everything else will
333         work in pretty much the same way. Lets start with forward iteration, by providing
334         a <code class="computeroutput"><span class="identifier">next_impl</span></code>:
335       </p>
336 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span>
337 <span class="keyword">struct</span> <span class="identifier">next_impl</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator_tag</span><span class="special">&gt;</span>
338 <span class="special">{</span>
339     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">&gt;</span>
340     <span class="keyword">struct</span> <span class="identifier">apply</span>
341     <span class="special">{</span>
342         <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">::</span><span class="identifier">struct_type</span> <span class="identifier">struct_type</span><span class="special">;</span>
343         <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">::</span><span class="identifier">index</span> <span class="identifier">index</span><span class="special">;</span>
344         <span class="keyword">typedef</span> <span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">struct_type</span><span class="special">,</span> <span class="identifier">index</span><span class="special">::</span><span class="identifier">value</span> <span class="special">+</span> <span class="number">1</span><span class="special">&gt;</span> <span class="identifier">type</span><span class="special">;</span>
345
346         <span class="keyword">static</span> <span class="identifier">type</span>
347         <span class="identifier">call</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">i</span><span class="special">)</span>
348         <span class="special">{</span>
349              <span class="keyword">return</span> <span class="identifier">type</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">struct_</span><span class="special">);</span>
350         <span class="special">}</span>
351     <span class="special">};</span>
352 <span class="special">};</span>
353 </pre>
354 <p>
355         This should be very familiar from our <code class="computeroutput"><span class="identifier">deref_impl</span></code>
356         implementation, we will be using this approach again and again now. Our design
357         is simply to increment the <code class="computeroutput"><span class="identifier">index</span></code>
358         counter to move on to the next element. The various other iterator manipulations
359         we need to perform will all just involve simple calculations with the <code class="computeroutput"><span class="identifier">index</span></code> variables.
360       </p>
361 <p>
362         We also need to provide a suitable <code class="computeroutput"><span class="identifier">equal_to_impl</span></code>
363         so that iterators can be correctly compared. A <a class="link" href="../iterator/concepts/bidirectional_iterator.html" title="Bidirectional Iterator">Bidirectional
364         Iterator</a> will also need an implementation of <code class="computeroutput"><span class="identifier">prior_impl</span></code>.
365         For a <a class="link" href="../iterator/concepts/random_access_iterator.html" title="Random Access Iterator">Random
366         Access Iterator</a> <code class="computeroutput"><span class="identifier">distance_impl</span></code>
367         and <code class="computeroutput"><span class="identifier">advance_impl</span></code> also need
368         to be provided in order to satisfy the necessary complexity guarantees. As
369         our iterator is a <a class="link" href="../iterator/concepts/random_access_iterator.html" title="Random Access Iterator">Random
370         Access Iterator</a> we will have to implement all of these functions.
371       </p>
372 <p>
373         Full implementations of <code class="computeroutput"><span class="identifier">prior_impl</span></code>,
374         <code class="computeroutput"><span class="identifier">advance_impl</span></code>, <code class="computeroutput"><span class="identifier">distance_impl</span></code> and <code class="computeroutput"><span class="identifier">equal_to_impl</span></code>
375         are provided in the example code.
376       </p>
377 <h5>
378 <a name="fusion.extension.ext_full.h5"></a>
379         <span class="phrase"><a name="fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence">Implementing
380         the intrinsic functions of the sequence</a>
381       </h5>
382 <p>
383         In order that Fusion can correctly identify our sequence as a Fusion sequence,
384         we need to enable <code class="computeroutput"><span class="identifier">is_sequence</span></code>
385         for our sequence type. As usual we just create an <code class="computeroutput"><span class="identifier">impl</span></code>
386         type specialized for our sequence tag:
387       </p>
388 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span>
389 <span class="keyword">struct</span> <span class="identifier">is_sequence_impl</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_sequence_tag</span><span class="special">&gt;</span>
390 <span class="special">{</span>
391     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
392     <span class="keyword">struct</span> <span class="identifier">apply</span> <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">true_</span> <span class="special">{};</span>
393 <span class="special">};</span>
394 </pre>
395 <p>
396         We've some similar formalities to complete, providing <code class="computeroutput"><span class="identifier">category_of_impl</span></code>
397         so Fusion can correctly identify our sequence type, and <code class="computeroutput"><span class="identifier">is_view_impl</span></code>
398         so Fusion can correctly identify our sequence as not being a <a class="link" href="../view.html" title="View">View</a>
399         type. Implementations are provide in the example code.
400       </p>
401 <p>
402         Now we've completed some formalities, on to more interesting features. Lets
403         get <a class="link" href="../sequence/intrinsic/functions/begin.html" title="begin"><code class="computeroutput"><span class="identifier">begin</span></code></a> working so that we can get
404         an iterator to start accessing the data in our sequence.
405       </p>
406 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span>
407 <span class="keyword">struct</span> <span class="identifier">begin_impl</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_sequence_tag</span><span class="special">&gt;</span>
408 <span class="special">{</span>
409     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">&gt;</span>
410     <span class="keyword">struct</span> <span class="identifier">apply</span>
411     <span class="special">{</span>
412         <span class="keyword">typedef</span> <span class="identifier">example</span><span class="special">::</span><span class="identifier">example_struct_iterator</span><span class="special">&lt;</span><span class="identifier">Sequence</span><span class="special">,</span> <span class="number">0</span><span class="special">&gt;</span> <span class="identifier">type</span><span class="special">;</span>
413
414         <span class="keyword">static</span> <span class="identifier">type</span>
415         <span class="identifier">call</span><span class="special">(</span><span class="identifier">Sequence</span><span class="special">&amp;</span> <span class="identifier">seq</span><span class="special">)</span>
416         <span class="special">{</span>
417             <span class="keyword">return</span> <span class="identifier">type</span><span class="special">(</span><span class="identifier">seq</span><span class="special">);</span>
418         <span class="special">}</span>
419     <span class="special">};</span>
420 <span class="special">};</span>
421 </pre>
422 <p>
423         The implementation uses the same ideas we have applied throughout, in this
424         case we are just creating one of the iterators we developed earlier, pointing
425         to the first element in the sequence. The implementation of <a class="link" href="../sequence/intrinsic/functions/end.html" title="end"><code class="computeroutput"><span class="identifier">end</span></code></a> is very similar, and is provided
426         in the example code.
427       </p>
428 <p>
429         For our <a class="link" href="../sequence/concepts/random_access_sequence.html" title="Random Access Sequence">Random
430         Access Sequence</a> we will also need to implement <code class="computeroutput"><span class="identifier">size_impl</span></code>,
431         <code class="computeroutput"><span class="identifier">value_at_impl</span></code> and <code class="computeroutput"><span class="identifier">at_impl</span></code>.
432       </p>
433 <h5>
434 <a name="fusion.extension.ext_full.h6"></a>
435         <span class="phrase"><a name="fusion.extension.ext_full.enabling_our_type_as_an_associative_sequence"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.enabling_our_type_as_an_associative_sequence">Enabling
436         our type as an associative sequence</a>
437       </h5>
438 <p>
439         In order for <code class="computeroutput"><span class="identifier">example_struct</span></code>
440         to serve as an associative forward sequence, we need to adapt the traversal
441         category of our sequence and our iterator accordingly and enable 3 intrinsic
442         sequence lookup features, <a class="link" href="../sequence/intrinsic/functions/at_key.html" title="at_key"><code class="computeroutput"><span class="identifier">at_key</span></code></a>, __value_at_key__ and <a class="link" href="../sequence/intrinsic/functions/has_key.html" title="has_key"><code class="computeroutput"><span class="identifier">has_key</span></code></a>.
443         We also need to enable 3 iterator lookup features, <a class="link" href="../iterator/metafunctions/key_of.html" title="key_of"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">key_of</span></code></a>, <a class="link" href="../iterator/metafunctions/value_of_data.html" title="value_of_data"><code class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of_data</span></code></a> and <a class="link" href="../iterator/functions/deref_data.html" title="deref_data"><code class="computeroutput"><span class="identifier">deref_data</span></code></a>.
444       </p>
445 <p>
446         To implement <code class="computeroutput"><span class="identifier">at_key_impl</span></code>
447         we need to associate the <code class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">name</span></code>
448         and <code class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">age</span></code> types described in the <a class="link" href="../quick_start.html" title="Quick Start">Quick
449         Start</a> guide with the appropriate members of <code class="computeroutput"><span class="identifier">example_struct</span></code>.
450         Our implementation is as follows:
451       </p>
452 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;&gt;</span>
453 <span class="keyword">struct</span> <span class="identifier">at_key_impl</span><span class="special">&lt;</span><span class="identifier">example</span><span class="special">::</span><span class="identifier">example_sequence_tag</span><span class="special">&gt;</span>
454 <span class="special">{</span>
455     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Key</span><span class="special">&gt;</span>
456     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">;</span>
457
458     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">&gt;</span>
459     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">Sequence</span><span class="special">,</span> <span class="identifier">fields</span><span class="special">::</span><span class="identifier">name</span><span class="special">&gt;</span>
460     <span class="special">{</span>
461         <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">if_</span><span class="special">&lt;</span>
462             <span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">Sequence</span><span class="special">&gt;,</span>
463             <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;,</span>
464             <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;&gt;::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span>
465
466         <span class="keyword">static</span> <span class="identifier">type</span>
467         <span class="identifier">call</span><span class="special">(</span><span class="identifier">Sequence</span><span class="special">&amp;</span> <span class="identifier">seq</span><span class="special">)</span>
468         <span class="special">{</span>
469             <span class="keyword">return</span> <span class="identifier">seq</span><span class="special">.</span><span class="identifier">name</span><span class="special">;</span>
470         <span class="special">};</span>
471     <span class="special">};</span>
472
473     <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">&gt;</span>
474     <span class="keyword">struct</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">Sequence</span><span class="special">,</span> <span class="identifier">fields</span><span class="special">::</span><span class="identifier">age</span><span class="special">&gt;</span>
475     <span class="special">{</span>
476         <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">if_</span><span class="special">&lt;</span>
477             <span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">Sequence</span><span class="special">&gt;,</span>
478             <span class="keyword">int</span> <span class="keyword">const</span><span class="special">&amp;,</span>
479             <span class="keyword">int</span><span class="special">&amp;&gt;::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span>
480
481         <span class="keyword">static</span> <span class="identifier">type</span>
482         <span class="identifier">call</span><span class="special">(</span><span class="identifier">Sequence</span><span class="special">&amp;</span> <span class="identifier">seq</span><span class="special">)</span>
483         <span class="special">{</span>
484             <span class="keyword">return</span> <span class="identifier">seq</span><span class="special">.</span><span class="identifier">age</span><span class="special">;</span>
485         <span class="special">};</span>
486     <span class="special">};</span>
487 <span class="special">};</span>
488 </pre>
489 <p>
490         Its all very similar to the implementations we've seen previously, such as
491         <code class="computeroutput"><span class="identifier">deref_impl</span></code> and <code class="computeroutput"><span class="identifier">value_of_impl</span></code>. Instead of identifying the
492         members by index or position, we are now selecting them using the types
493         <code class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">name</span></code> and <code class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">age</span></code>.
494         The implementations of the other functions are equally straightforward, and
495         are provided in the example code.
496       </p>
497 <h5>
498 <a name="fusion.extension.ext_full.h7"></a>
499         <span class="phrase"><a name="fusion.extension.ext_full.summary"></a></span><a class="link" href="ext_full.html#fusion.extension.ext_full.summary">Summary</a>
500       </h5>
501 <p>
502         We've now worked through the entire process for adding a new random access
503         sequence and we've also enabled our type to serve as an associative sequence.
504         The implementation was slightly longwinded, but followed a simple repeating
505         pattern.
506       </p>
507 <p>
508         The support for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>, <a href="http://www.boost.org/libs/mpl/index.html" target="_top">MPL</a>
509         sequences, and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code> all use the same approach, and provide
510         additional examples of the approach for a variety of types.
511       </p>
512 </div>
513 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
514 <td align="left"></td>
515 <td align="right"><div class="copyright-footer">Copyright &#169; 2001-2006, 2011, 2012 Joel de Guzman,
516       Dan Marsden, Tobias Schwinger<p>
517         Distributed under the Boost Software License, Version 1.0. (See accompanying
518         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>)
519       </p>
520 </div></td>
521 </tr></table>
522 <hr>
523 <div class="spirit-nav">
524 <a accesskey="p" href="../extension.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../extension.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="sequence_facade.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
525 </div>
526 </body>
527 </html>