The Fusion library is designed to be extensible, new sequences types can easily
be added. In fact, the library support for <ttclass="computeroutput"><spanclass="identifier">std</span><spanclass="special">::</span><spanclass="identifier">pair</span></tt>,
<ttclass="computeroutput"><spanclass="identifier">boost</span><spanclass="special">::</span><spanclass="identifier">array</span></tt> and <ahref="http://www.boost.org/libs/mpl/index.html"target="_top">MPL</a>
sequences is entirely provided using the extension mechanism.
</p>
<p>
The process for adding a new sequence type to Fusion is:
</p>
<divclass="orderedlist"><oltype="1">
<li>
Enable the <ahref="notes.html#fusion.notes.tag_dispatching"><spanclass="emphasis"><em>tag dispatching</em></span></a>
mechanism used by Fusion for your sequence type
</li>
<li>
Design an iterator type for the sequence
</li>
<li>
Provide specialized behaviour for the intrinsic operations of the new Fusion
<spanclass="keyword">struct</span><spanclass="identifier">example_sequence_tag</span><spanclass="special">;</span><spanclass="comment">// Only definition needed
Next we need to enable the <ttclass="computeroutput"><spanclass="identifier">traits</span><spanclass="special">::</span><spanclass="identifier">tag_of</span></tt>
metafunction to return our newly chosen tag type for operations involving our
sequence. This is done by specializing <ttclass="computeroutput"><spanclass="identifier">traits</span><spanclass="special">::</span><spanclass="identifier">tag_of</span></tt>
<ttclass="computeroutput"><spanclass="identifier">traits</span><spanclass="special">::</span><spanclass="identifier">tag_of</span></tt> also has a second template argument,
that can be used in conjuction with <ttclass="computeroutput"><spanclass="identifier">boost</span><spanclass="special">::</span><spanclass="identifier">enable_if</span></tt>
The iterator is parameterized by the type it is iterating over, and the index
of the current element.
</li>
<li>
The typedefs <ttclass="computeroutput"><spanclass="identifier">struct_type</span></tt>
and <ttclass="computeroutput"><spanclass="identifier">index</span></tt> provide convenient
access to information we will need later in the implementation.
</li>
<li>
The typedef <ttclass="computeroutput"><spanclass="identifier">category</span></tt> allows
the <ttclass="computeroutput"><spanclass="identifier">traits</span><spanclass="special">::</span><ahref="support/category_of.html"title="category_of"><ttclass="computeroutput"><spanclass="identifier">category_of</span></tt></a></tt>
metafunction to establish the traversal category of the iterator.
</li>
<li>
The constructor stores a reference to the <ttclass="computeroutput"><spanclass="identifier">example_struct</span></tt>
being iterated over.
</li>
</ol></div>
<p>
We also need to enable <ahref="notes.html#fusion.notes.tag_dispatching"><spanclass="emphasis"><em>tag
dispatching</em></span></a> for our iterator type, with another specialization
<ahref="extension.html#fusion.extension.a_first_couple_of_instructive_features">A first
couple of instructive features</a>
</h3>
<p>
To start with, we will get the <ahref="iterators/metafunctions/value_of.html"title="value_of"><ttclass="computeroutput"><spanclass="identifier">result_of</span><spanclass="special">::</span><spanclass="identifier">value_of</span></tt></a> metafunction working. To
do this, we provide a specialization of the <ttclass="computeroutput"><spanclass="identifier">boost</span><spanclass="special">::</span><spanclass="identifier">fusion</span><spanclass="special">::</span><spanclass="identifier">extension</span><spanclass="special">::</span><spanclass="identifier">value_of_impl</span></tt>
The implementation itself is pretty simple, it just uses 2 partial specializations
to provide the type of the 2 different members of <ttclass="computeroutput"><spanclass="identifier">example_struct</span></tt>,
based on the index of the iterator.
</p>
<p>
To understand how <ttclass="computeroutput"><spanclass="identifier">value_of_impl</span></tt>
is used by the library we will look at the implementation of <ahref="iterators/metafunctions/value_of.html"title="value_of"><ttclass="computeroutput"><spanclass="identifier">value_of</span></tt></a>:
The use of <ttclass="computeroutput"><spanclass="identifier">deref_impl</span></tt> is very
similar to that of <ttclass="computeroutput"><spanclass="identifier">value_of_impl</span></tt>,
but it also provides some runtime functionality this time via the <ttclass="computeroutput"><spanclass="identifier">call</span></tt> static member function. To see how
<ttclass="computeroutput"><spanclass="identifier">deref_impl</span></tt> is used, lets have
a look at the implementation of <ahref="iterators/functions/deref.html"title="deref"><ttclass="computeroutput"><spanclass="identifier">deref</span></tt></a>:
So again <ahref="iterators/metafunctions/deref.html"title="deref"><ttclass="computeroutput"><spanclass="identifier">result_of</span><spanclass="special">::</span><spanclass="identifier">deref</span></tt></a> uses <ahref="notes.html#fusion.notes.tag_dispatching"><spanclass="emphasis"><em>tag
dispatching</em></span></a> in exactly the same way as the <ahref="iterators/metafunctions/value_of.html"title="value_of"><ttclass="computeroutput"><spanclass="identifier">value_of</span></tt></a> implementation. The runtime
functionality used by <ahref="iterators/functions/deref.html"title="deref"><ttclass="computeroutput"><spanclass="identifier">deref</span></tt></a> is provided by the <ttclass="computeroutput"><spanclass="identifier">call</span></tt> static function of the selected MPL
Metafunction Class.
</p>
<p>
The actual implementation of <ttclass="computeroutput"><spanclass="identifier">deref_impl</span></tt>
is slightly more complex than that of <ttclass="computeroutput"><spanclass="identifier">value_of_impl</span></tt>.
We also need to implement the <ttclass="computeroutput"><spanclass="identifier">call</span></tt>
function, which returns a reference to the appropriate member of the underlying
sequence. We also require a little bit of metaprogramming to return <ttclass="computeroutput"><spanclass="keyword">const</span></tt> references if the underlying sequence
Although there is a fair amount of left to do to produce a fully fledged
Fusion sequence, <ahref="iterators/metafunctions/value_of.html"title="value_of"><ttclass="computeroutput"><spanclass="identifier">value_of</span></tt></a> and <ahref="iterators/functions/deref.html"title="deref"><ttclass="computeroutput"><spanclass="identifier">deref</span></tt></a> illustrate all the signficant
concepts required. The remainder of the process is very repetitive, simply
requiring implementation of a suitable <ttclass="computeroutput"><spanclass="identifier">xxxx_impl</span></tt>
for each feature <ttclass="computeroutput"><spanclass="identifier">xxxx</span></tt>.
Ok, now we have seen the way <ahref="iterators/metafunctions/value_of.html"title="value_of"><ttclass="computeroutput"><spanclass="identifier">value_of</span></tt></a> and <ahref="iterators/functions/deref.html"title="deref"><ttclass="computeroutput"><spanclass="identifier">deref</span></tt></a> work, everything else will work
in pretty much the same way. Lets start with forward iteration, by providing
a <ttclass="computeroutput"><spanclass="identifier">next_impl</span></tt>:
and <ttclass="computeroutput"><spanclass="identifier">advance_impl</span></tt> also need
to be provided in order to satisfy the necessary complexity guarantees. As
our iterator is a <ahref="iterators/concepts/random_access_iterator.html"title="Random
Access Iterator">Random
Access Iterator</a> we will have to implement all of these functions.
</p>
<p>
Full implementations of <ttclass="computeroutput"><spanclass="identifier">prior_impl</span></tt>,
<ttclass="computeroutput"><spanclass="identifier">advance_impl</span></tt>, <ttclass="computeroutput"><spanclass="identifier">distance_impl</span></tt> and <ttclass="computeroutput"><spanclass="identifier">equal_to_impl</span></tt>
We've some similar formalities to complete, providing <ttclass="computeroutput"><spanclass="identifier">category_of_impl</span></tt>
so Fusion can correctly identify our sequence type, and <ttclass="computeroutput"><spanclass="identifier">is_view_impl</span></tt>
so Fusion can correctly identify our sequence as not being a <ahref="sequences/views.html"title="Views">View</a>
type. Implementations are provide in the example code.
</p>
<p>
Now we've completed some formalities, on to more interesting features. Lets
get <ahref="sequences/intrinsics/functions/begin.html"title="begin"><ttclass="computeroutput"><spanclass="identifier">begin</span></tt></a> working so that we can get an
iterator to start accessing the data in our sequence.
The implementation uses the same ideas we have applied throughout, in this
case we are just creating one of the iterators we developed earlier, pointing
to the first element in the sequence. The implementation of <ahref="sequences/intrinsics/functions/end.html"title="end"><ttclass="computeroutput"><spanclass="identifier">end</span></tt></a> is very similar, and is provided
in the example code.
</p>
<p>
For our <ahref="sequences/concepts/random_access_sequence.html"title="Random
Access Sequence">Random
Access Sequence</a> we will also need to implement <ttclass="computeroutput"><spanclass="identifier">size_impl</span></tt>,
<ttclass="computeroutput"><spanclass="identifier">value_at_impl</span></tt> and <ttclass="computeroutput"><spanclass="identifier">at_impl</span></tt>.
In order for <ttclass="computeroutput"><spanclass="identifier">example_struct</span></tt>
to serve as an associative container, we need to enable 3 lookup features,
<ahref="sequences/intrinsics/functions/at_key.html"title="at_key"><ttclass="computeroutput"><spanclass="identifier">at_key</span></tt></a>, <ahref="sequences/intrinsics/metafunctions/value_at_key.html"title="value_at_key"><ttclass="computeroutput"><spanclass="identifier">value_at_key</span></tt></a> and <ahref="sequences/intrinsics/functions/has_key.html"title="has_key"><ttclass="computeroutput"><spanclass="identifier">has_key</span></tt></a>. We also need to provide an
implementation of the <ttclass="computeroutput"><spanclass="identifier">is_associative</span></tt>
trait so that our sequence can be correctly identified as an associative container.
</p>
<p>
To implement <ttclass="computeroutput"><spanclass="identifier">at_key_impl</span></tt> we
need to associate the <ttclass="computeroutput"><spanclass="identifier">fields</span><spanclass="special">::</span><spanclass="identifier">age</span></tt> and
<ttclass="computeroutput"><spanclass="identifier">fields</span><spanclass="special">::</span><spanclass="identifier">age</span></tt> types described in the <ahref="quick_start.html"title="Quick Start">Quick
Start</a> guide with the appropriate members of <ttclass="computeroutput"><spanclass="identifier">example_struct</span></tt>.
Its all very similar to the implementations we've seen previously, such as
<ttclass="computeroutput"><spanclass="identifier">deref_impl</span></tt> and <ttclass="computeroutput"><spanclass="identifier">value_of_impl</span></tt>. Instead of identifying the
members by index or position, we are now selecting them using the types <ttclass="computeroutput"><spanclass="identifier">fields</span><spanclass="special">::</span><spanclass="identifier">name</span></tt> and <ttclass="computeroutput"><spanclass="identifier">fields</span><spanclass="special">::</span><spanclass="identifier">age</span></tt>. The
implementations of <ttclass="computeroutput"><spanclass="identifier">value_at_key_impl</span></tt>
and <ttclass="computeroutput"><spanclass="identifier">has_key_impl</span></tt> are equally
straightforward, and are provided in the example code, along with an implementation
of <ttclass="computeroutput"><spanclass="identifier">is_associative_impl</span></tt>.
We've now worked through the entire process for adding a new random access
sequence and we've also enabled our type to serve as an associative container.
The implementation was slightly longwinded, but followed a simple repeating
pattern.
</p>
<p>
The support for <ttclass="computeroutput"><spanclass="identifier">std</span><spanclass="special">::</span><spanclass="identifier">pair</span></tt>, <ahref="http://www.boost.org/libs/mpl/index.html"target="_top">MPL</a>
sequences, and <ttclass="computeroutput"><spanclass="identifier">boost</span><spanclass="special">::</span><spanclass="identifier">array</span></tt> all use the same approach, and provide
additional examples of the approach for a variety of types.