2006-08-22 15:57:13 +00:00
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=ISO-8859-1" >
< title > Extension< / title >
< link rel = "stylesheet" href = "../boostbook.css" type = "text/css" >
2007-02-15 23:11:24 +00:00
< meta name = "generator" content = "DocBook XSL Stylesheets V1.68.1" >
2006-08-22 15:57:13 +00:00
< link rel = "start" href = "../index.html" title = "Chapter<65> 1.<2E> Fusion 2.0" >
< link rel = "up" href = "../index.html" title = "Chapter<65> 1.<2E> Fusion 2.0" >
< link rel = "prev" href = "tuples/pairs.html" title = "Pairs" >
2007-02-15 23:11:24 +00:00
< link rel = "next" href = "functional.html" title = "Functional" >
2006-08-22 15:57:13 +00:00
< / head >
< body bgcolor = "white" text = "black" link = "#0000FF" vlink = "#840084" alink = "#0000FF" >
< table cellpadding = "2" width = "100%" >
< td valign = "top" > < img alt = "Boost C++ Libraries" width = "277" height = "86" src = "../../../../../boost.png" > < / td >
< td align = "center" > < a href = "../../../../../index.htm" > Home< / a > < / td >
< td align = "center" > < a href = "../../../../libraries.htm" > Libraries< / a > < / td >
< td align = "center" > < a href = "../../../../../people/people.htm" > People< / a > < / td >
< td align = "center" > < a href = "../../../../../more/faq.htm" > FAQ< / a > < / td >
< td align = "center" > < a href = "../../../../../more/index.htm" > More< / a > < / td >
< / table >
< hr >
< div class = "spirit-nav" >
2007-02-15 23:11:24 +00:00
< a accesskey = "p" href = "tuples/pairs.html" > < img src = "../images/prev.png" alt = "Prev" > < / a > < a accesskey = "u" href = "../index.html" > < img src = "../images/up.png" alt = "Up" > < / a > < a accesskey = "h" href = "../index.html" > < img src = "../images/home.png" alt = "Home" > < / a > < a accesskey = "n" href = "functional.html" > < img src = "../images/next.png" alt = "Next" > < / a >
2006-08-22 15:57:13 +00:00
< / div >
< div class = "section" lang = "en" >
< div class = "titlepage" > < div > < div > < h2 class = "title" style = "clear: both" >
< a name = "fusion.extension" > < / a > < a href = "extension.html" title = "Extension" > Extension< / a > < / h2 > < / div > < / div > < / div >
< p >
The Fusion library is designed to be extensible, new sequences types can easily
2007-02-15 23:11:24 +00:00
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 > ,
< 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 >
2006-08-22 15:57:13 +00:00
sequences is entirely provided using the extension mechanism.
< / p >
< p >
The process for adding a new sequence type to Fusion is:
< / p >
< div class = "orderedlist" > < ol type = "1" >
< li >
Enable the < a href = "notes.html#fusion.notes.tag_dispatching" > < span class = "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
sequence
< / li >
< / ol > < / div >
< a name = "fusion.extension.our_example" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1181263" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.our_example" > Our example< / a >
< / h3 >
< p >
In order to illustrate enabling a new sequence type for use with Fusion, we
are going to use the type:
< / p >
< pre class = "programlisting" >
< span class = "keyword" > namespace< / span > < span class = "identifier" > example< / span >
< span class = "special" > {< / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > example_struct< / span >
< span class = "special" > {< / span >
< span class = "identifier" > std< / span > < span class = "special" > ::< / span > < span class = "identifier" > string< / span > < span class = "identifier" > name< / span > < span class = "special" > ;< / span >
< span class = "keyword" > int< / span > < span class = "identifier" > age< / span > < span class = "special" > ;< / span >
< span class = "identifier" > example_struct< / span > < span class = "special" > (< / span >
< span class = "keyword" > const< / span > < span class = "identifier" > std< / span > < span class = "special" > ::< / span > < span class = "identifier" > string< / span > < span class = "special" > & < / span > < span class = "identifier" > n< / span > < span class = "special" > ,< / span >
< span class = "keyword" > int< / span > < span class = "identifier" > a< / span > < span class = "special" > )< / span >
< 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 >
< span class = "special" > {}< / span >
< span class = "special" > };< / span >
< span class = "special" > }< / span >
< / pre >
< p >
We are going to pretend that this type has been provided by a 3rd party library,
and therefore cannot be modified. We shall work through all the necessary steps
2007-02-15 23:11:24 +00:00
to enable < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code > to
2006-08-22 15:57:13 +00:00
serve as an < a href = "sequences/concepts/associative_sequence.html" title = "Associative
Sequence">Associative
Sequence< / a > as described in the < a href = "quick_start.html" title = "Quick Start" > Quick
Start< / a > guide.
< / p >
< a name = "fusion.extension.enabling_tag_dispatching" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1181516" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.enabling_tag_dispatching" > Enabling Tag Dispatching< / a >
< / h3 >
< p >
The Fusion extensibility mechanism uses < a href = "notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag
dispatching< / em > < / span > < / a > to call the correct code for a given sequence
type. In order to exploit the tag dispatching mechanism we must first declare
a new tag type for the mechanism to use. For example:
< / p >
< pre class = "programlisting" >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > namespace< / span > < span class = "identifier" > example< / span > < span class = "special" > {< / span >
2006-08-22 15:57:13 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > example_sequence_tag< / span > < span class = "special" > ;< / span > < span class = "comment" > // Only definition needed
2006-10-30 01:20:23 +00:00
< / span > < span class = "special" > }< / span >
2006-08-22 15:57:13 +00:00
< / pre >
< p >
2007-02-15 23:11:24 +00:00
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 >
2006-08-22 15:57:13 +00:00
metafunction to return our newly chosen tag type for operations involving our
2007-02-15 23:11:24 +00:00
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 >
2006-08-22 15:57:13 +00:00
for our sequence type.
< / p >
< pre class = "programlisting" >
< span class = "preprocessor" > #include< / span > < 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" > 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" > > < / span >
2006-10-30 01:20:23 +00:00
< 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 >
2006-08-22 15:57:13 +00:00
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > tag_of< / span > < span class = "special" > < < / span > < span class = "identifier" > example_struct< / span > < span class = "special" > > < / span >
< span class = "special" > {< / span >
2006-10-30 01:20:23 +00:00
< 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 >
2006-08-22 15:57:13 +00:00
< span class = "special" > };< / span >
< span class = "special" > }}}< / span >
< / pre >
< p >
2007-02-15 23:11:24 +00:00
< 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,
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 >
2006-10-30 01:20:23 +00:00
to provide tag support for groups of related types. This feature is not necessary
2006-08-22 15:57:13 +00:00
for our sequence, but for an example see the code in:
< / p >
< pre class = "programlisting" >
< span class = "preprocessor" > #include< / span > < 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" > sequence< / span > < span class = "special" > /< / span > < span class = "identifier" > adapted< / span > < span class = "special" > /< / span > < span class = "identifier" > mpl< / span > < span class = "special" > /< / span > < span class = "identifier" > tag_of< / span > < span class = "special" > .< / span > < span class = "identifier" > hpp< / span > < span class = "special" > > < / span >
< / pre >
< a name = "fusion.extension.designing_a_suitable_iterator" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1181956" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.designing_a_suitable_iterator" > Designing a
suitable iterator< / a >
< / h3 >
< p >
We need an iterator to describe positions, and provide access to the data within
our sequence. As it is straightforward to do, we are going to provide a random
access iterator in our example.
< / p >
< p >
2007-02-15 23:11:24 +00:00
We will use a simple design, in which the 2 members of < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code >
are given numbered indices, 0 for < code class = "computeroutput" > < span class = "identifier" > name< / span > < / code >
and 1 for < code class = "computeroutput" > < span class = "identifier" > age< / span > < / code > respectively.
2006-08-22 15:57:13 +00:00
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < < / 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" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > example_struct_iterator< / span >
2006-10-30 01:20:23 +00:00
< 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" > < < / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "identifier" > Pos< / span > < span class = "special" > > < / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "identifier" > BOOST_STATIC_ASSERT< / span > < span class = "special" > (< / span > < span class = "identifier" > Pos< / span > < span class = "special" > > =< / span > < span class = "number" > 0< / span > < span class = "special" > & & < / span > < span class = "identifier" > Pos< / span > < span class = "special" > < < / span > < span class = "number" > 3< / span > < span class = "special" > );< / span >
< span class = "keyword" > typedef< / span > < span class = "identifier" > Struct< / span > < span class = "identifier" > struct_type< / span > < span class = "special" > ;< / span >
2006-10-30 01:20:23 +00:00
< 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" > < < / span > < span class = "identifier" > Pos< / span > < span class = "special" > > < / span > < span class = "identifier" > index< / span > < span class = "special" > ;< / span >
< 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 >
2006-08-22 15:57:13 +00:00
< span class = "identifier" > example_struct_iterator< / span > < 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 > < span class = "identifier" > struct_< / span > < span class = "special" > (< / span > < span class = "identifier" > str< / span > < span class = "special" > )< / span > < span class = "special" > {}< / span >
< span class = "identifier" > Struct< / span > < span class = "special" > & < / span > < span class = "identifier" > struct_< / span > < span class = "special" > ;< / span >
< span class = "special" > };< / span >
< / pre >
< p >
A quick summary of the details of our iterator:
< / p >
< div class = "orderedlist" > < ol type = "1" >
< li >
The iterator is parameterized by the type it is iterating over, and the index
of the current element.
< / li >
< li >
2007-02-15 23:11:24 +00:00
The typedefs < code class = "computeroutput" > < span class = "identifier" > struct_type< / span > < / code >
and < code class = "computeroutput" > < span class = "identifier" > index< / span > < / code > provide convenient
2006-08-22 15:57:13 +00:00
access to information we will need later in the implementation.
< / li >
< li >
2007-02-15 23:11:24 +00:00
The typedef < code class = "computeroutput" > < span class = "identifier" > category< / span > < / code > allows
the < code class = "computeroutput" > < span class = "identifier" > traits< / span > < span class = "special" > ::< / span > < a href = "support/category_of.html" title = "category_of" > < code class = "computeroutput" > < span class = "identifier" > category_of< / span > < / code > < / a > < / code >
2006-08-22 15:57:13 +00:00
metafunction to establish the traversal category of the iterator.
< / li >
< li >
2007-02-15 23:11:24 +00:00
The constructor stores a reference to the < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code >
2006-08-22 15:57:13 +00:00
being iterated over.
< / li >
< / ol > < / div >
< p >
We also need to enable < a href = "notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag
dispatching< / em > < / span > < / a > for our iterator type, with another specialization
2007-02-15 23:11:24 +00:00
of < code class = "computeroutput" > < span class = "identifier" > traits< / span > < span class = "special" > ::< / span > < span class = "identifier" > tag_of< / span > < / code > .
2006-08-22 15:57:13 +00:00
< / p >
< p >
In isolation, the iterator implementation is pretty dry. Things should become
clearer as we add features to our implementation.
< / p >
< a name = "fusion.extension.a_first_couple_of_instructive_features" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1182523" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.a_first_couple_of_instructive_features" > A first
couple of instructive features< / a >
< / h3 >
< p >
2007-02-15 23:11:24 +00:00
To start with, we will get the < a href = "iterators/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
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 >
2006-08-22 15:57:13 +00:00
template for our iterator's tag type.
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > value_of_impl< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator_tag< / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > ;< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Struct< / span > < span class = "special" > > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "number" > 0< / span > < span class = "special" > > < / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< 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 >
< span class = "special" > };< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Struct< / span > < span class = "special" > > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "number" > 1< / span > < span class = "special" > > < / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > typedef< / span > < span class = "keyword" > int< / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< / pre >
< p >
The implementation itself is pretty simple, it just uses 2 partial specializations
2007-02-15 23:11:24 +00:00
to provide the type of the 2 different members of < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code > ,
2006-08-22 15:57:13 +00:00
based on the index of the iterator.
< / p >
< p >
2007-02-15 23:11:24 +00:00
To understand how < code class = "computeroutput" > < span class = "identifier" > value_of_impl< / span > < / code >
is used by the library we will look at the implementation of < a href = "iterators/metafunctions/value_of.html" title = "value_of" > < code class = "computeroutput" > < span class = "identifier" > value_of< / span > < / code > < / a > :
2006-08-22 15:57:13 +00:00
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
2007-02-15 23:11:24 +00:00
< span class = "keyword" > struct< / span > < a href = "iterators/metafunctions/value_of.html" title = "value_of" > < code class = "computeroutput" > < span class = "identifier" > value_of< / span > < / code > < / a >
2006-10-30 01:20:23 +00:00
< span class = "special" > :< / span > < span class = "identifier" > extension< / span > < span class = "special" > ::< / span > < span class = "identifier" > value_of_impl< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > detail< / span > < span class = "special" > ::< / span > < span class = "identifier" > tag_of< / span > < span class = "special" > < < / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > ::< / span > < span class = "identifier" > type< / span > < span class = "special" > > ::< / span >
< span class = "keyword" > template< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
< span class = "special" > {};< / span >
2006-08-22 15:57:13 +00:00
< / pre >
< p >
2007-02-15 23:11:24 +00:00
So < a href = "iterators/metafunctions/value_of.html" title = "value_of" > < code class = "computeroutput" > < span class = "identifier" > value_of< / span > < / code > < / a >
2006-08-22 15:57:13 +00:00
uses < a href = "notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag dispatching< / em > < / span > < / a >
2007-02-15 23:11:24 +00:00
to select an < a href = "http://www.boost.org/libs/mpl/doc/refmanual/metafunction-class.html" target = "_top" > MPL
Metafunction Class< / a > to provide its functionality. You will notice this
pattern throughout the implementation of Fusion.
2006-08-22 15:57:13 +00:00
< / p >
< p >
Ok, lets enable dereferencing of our iterator. In this case we must provide
2007-02-15 23:11:24 +00:00
a suitable specialization of < code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code > .
2006-08-22 15:57:13 +00:00
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > deref_impl< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator_tag< / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > ;< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Struct< / span > < span class = "special" > > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "number" > 0< / span > < span class = "special" > > < / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< 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" > < < / span >
< span class = "identifier" > is_const< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > > ,< / span > < span class = "identifier" > std< / span > < span class = "special" > ::< / span > < span class = "identifier" > string< / span > < span class = "keyword" > const< / span > < span class = "special" > & ,< / span > < span class = "identifier" > std< / span > < span class = "special" > ::< / span > < span class = "identifier" > string< / span > < span class = "special" > & > ::< / span > < span class = "identifier" > type< / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
< span class = "keyword" > static< / span > < span class = "identifier" > type< / span >
2006-10-30 01:20:23 +00:00
< 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" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "number" > 0< / span > < span class = "special" > > < / span > < span class = "keyword" > const< / span > < span class = "special" > & < / span > < span class = "identifier" > it< / span > < span class = "special" > )< / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< 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 >
< span class = "special" > }< / span >
< span class = "special" > };< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Struct< / span > < span class = "special" > > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "number" > 1< / span > < span class = "special" > > < / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< 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" > < < / span >
< span class = "identifier" > is_const< / span > < span class = "special" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > > ,< / span > < span class = "keyword" > int< / span > < span class = "keyword" > const< / span > < span class = "special" > & ,< / span > < span class = "keyword" > int< / span > < span class = "special" > & > ::< / span > < span class = "identifier" > type< / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
< span class = "keyword" > static< / span > < span class = "identifier" > type< / span >
2006-10-30 01:20:23 +00:00
< 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" > < < / span > < span class = "identifier" > Struct< / span > < span class = "special" > ,< / span > < span class = "number" > 1< / span > < span class = "special" > > < / span > < span class = "keyword" > const< / span > < span class = "special" > & < / span > < span class = "identifier" > it< / span > < span class = "special" > )< / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
2006-10-30 01:20:23 +00:00
< 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 >
< span class = "special" > }< / span >
< span class = "special" > };< / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > };< / span >
2006-10-30 01:20:23 +00:00
< span class = "special" > }< / span >
2006-08-22 15:57:13 +00:00
< / pre >
< p >
2007-02-15 23:11:24 +00:00
The use of < code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code > is very
similar to that of < code class = "computeroutput" > < span class = "identifier" > value_of_impl< / span > < / code > ,
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
< code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code > is used, lets have
a look at the implementation of < a href = "iterators/functions/deref.html" title = "deref" > < code class = "computeroutput" > < span class = "identifier" > deref< / span > < / code > < / a > :
2006-08-22 15:57:13 +00:00
< / p >
< pre class = "programlisting" >
< span class = "keyword" > namespace< / span > < span class = "identifier" > result_of< / span >
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
2007-02-15 23:11:24 +00:00
< span class = "keyword" > struct< / span > < a href = "iterators/functions/deref.html" title = "deref" > < code class = "computeroutput" > < span class = "identifier" > deref< / span > < / code > < / a >
2006-10-30 01:20:23 +00:00
< span class = "special" > :< / span > < span class = "identifier" > extension< / span > < span class = "special" > ::< / span > < span class = "identifier" > deref_impl< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > detail< / span > < span class = "special" > ::< / span > < span class = "identifier" > tag_of< / span > < span class = "special" > < < / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > ::< / span > < span class = "identifier" > type< / span > < span class = "special" > > ::< / span >
< span class = "keyword" > template< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
< span class = "special" > {};< / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > }< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > typename< / span > < span class = "identifier" > result_of< / span > < span class = "special" > ::< / span > < span class = "identifier" > deref< / span > < span class = "special" > < < / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > ::< / span > < span class = "identifier" > type< / span >
2007-02-15 23:11:24 +00:00
< a href = "iterators/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" > & < / span > < span class = "identifier" > i< / span > < span class = "special" > )< / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > typedef< / span > < span class = "identifier" > result_of< / span > < span class = "special" > ::< / span > < span class = "identifier" > deref< / span > < span class = "special" > < < / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span > < span class = "identifier" > deref_meta< / span > < span class = "special" > ;< / span >
< 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 >
2006-08-22 15:57:13 +00:00
< span class = "special" > }< / span >
< / pre >
< p >
2007-02-15 23:11:24 +00:00
So again < a href = "iterators/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 href = "notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag
dispatching< / em > < / span > < / a > in exactly the same way as the < a href = "iterators/metafunctions/value_of.html" title = "value_of" > < code class = "computeroutput" > < span class = "identifier" > value_of< / span > < / code > < / a > implementation. The runtime
functionality used by < a href = "iterators/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
Metafunction Class< / a > .
2006-08-22 15:57:13 +00:00
< / p >
< p >
2007-02-15 23:11:24 +00:00
The actual implementation of < code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code >
is slightly more complex than that of < code class = "computeroutput" > < span class = "identifier" > value_of_impl< / span > < / code > .
We also need to implement the < code class = "computeroutput" > < span class = "identifier" > call< / span > < / code >
2006-08-22 15:57:13 +00:00
function, which returns a reference to the appropriate member of the underlying
2007-02-15 23:11:24 +00:00
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
2006-08-22 15:57:13 +00:00
is const.
< / p >
< div class = "note" > < table border = "0" summary = "Note" >
< tr >
< td rowspan = "2" align = "center" valign = "top" width = "25" > < img alt = "[Note]" src = "../images/note.png" > < / td >
< th align = "left" > Note< / th >
< / tr >
2007-02-15 23:11:24 +00:00
< tr > < td align = "left" valign = "top" > < p >
2006-08-22 15:57:13 +00:00
Although there is a fair amount of left to do to produce a fully fledged
2007-02-15 23:11:24 +00:00
Fusion sequence, < a href = "iterators/metafunctions/value_of.html" title = "value_of" > < code class = "computeroutput" > < span class = "identifier" > value_of< / span > < / code > < / a > and < a href = "iterators/functions/deref.html" title = "deref" > < code class = "computeroutput" > < span class = "identifier" > deref< / span > < / code > < / a > illustrate all the signficant
2006-08-22 15:57:13 +00:00
concepts required. The remainder of the process is very repetitive, simply
2007-02-15 23:11:24 +00:00
requiring implementation of a suitable < code class = "computeroutput" > < span class = "identifier" > xxxx_impl< / span > < / code >
for each feature < code class = "computeroutput" > < span class = "identifier" > xxxx< / span > < / code > .
2006-08-22 15:57:13 +00:00
< / p > < / td > < / tr >
< / table > < / div >
< a name = "fusion.extension.implementing_the_remaining_iterator_functionality" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1184528" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.implementing_the_remaining_iterator_functionality" > Implementing
the remaining iterator functionality< / a >
< / h3 >
< p >
2007-02-15 23:11:24 +00:00
Ok, now we have seen the way < a href = "iterators/metafunctions/value_of.html" title = "value_of" > < code class = "computeroutput" > < span class = "identifier" > value_of< / span > < / code > < / a > and < a href = "iterators/functions/deref.html" title = "deref" > < code class = "computeroutput" > < span class = "identifier" > deref< / span > < / code > < / a > work, everything else will work
2006-08-22 15:57:13 +00:00
in pretty much the same way. Lets start with forward iteration, by providing
2007-02-15 23:11:24 +00:00
a < code class = "computeroutput" > < span class = "identifier" > next_impl< / span > < / code > :
2006-08-22 15:57:13 +00:00
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > next_impl< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator_tag< / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Iterator< / span > < span class = "special" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span >
< span class = "special" > {< / span >
< 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 >
< 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 >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > typedef< / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / 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" > > < / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
2006-08-22 15:57:13 +00:00
< span class = "keyword" > static< / span > < span class = "identifier" > type< / span >
< span class = "identifier" > call< / span > < span class = "special" > (< / span > < span class = "identifier" > Iterator< / span > < span class = "keyword" > const< / span > < span class = "special" > & < / span > < span class = "identifier" > i< / span > < span class = "special" > )< / span >
< span class = "special" > {< / span >
2006-10-30 01:20:23 +00:00
< 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 >
2006-08-22 15:57:13 +00:00
< span class = "special" > }< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< / pre >
< p >
2007-02-15 23:11:24 +00:00
This should be very familiar from our < code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code >
2006-08-22 15:57:13 +00:00
implementation, we will be using this approach again and again now. Our design
2007-02-15 23:11:24 +00:00
is simply to increment the < code class = "computeroutput" > < span class = "identifier" > index< / span > < / code >
2006-08-22 15:57:13 +00:00
counter to move on to the next element. The various other iterator manipulations
2007-02-15 23:11:24 +00:00
we need to perform will all just involve simple calculations with the < code class = "computeroutput" > < span class = "identifier" > index< / span > < / code > variables.
2006-08-22 15:57:13 +00:00
< / p >
< p >
2007-02-15 23:11:24 +00:00
We also need to provide a suitable < code class = "computeroutput" > < span class = "identifier" > equal_to_impl< / span > < / code >
2006-08-22 15:57:13 +00:00
so that iterators can be correctly compared. A < a href = "iterators/concepts/bidirectional_iterator.html" title = "Bidirectional
Iterator">Bidirectional
2007-02-15 23:11:24 +00:00
Iterator< / a > will also need an implementation of < code class = "computeroutput" > < span class = "identifier" > prior_impl< / span > < / code > .
2006-08-22 15:57:13 +00:00
For a < a href = "iterators/concepts/random_access_iterator.html" title = "Random
Access Iterator">Random
2007-02-15 23:11:24 +00:00
Access Iterator< / a > < code class = "computeroutput" > < span class = "identifier" > distance_impl< / span > < / code >
and < code class = "computeroutput" > < span class = "identifier" > advance_impl< / span > < / code > also need
2006-08-22 15:57:13 +00:00
to be provided in order to satisfy the necessary complexity guarantees. As
our iterator is a < a href = "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 >
2007-02-15 23:11:24 +00:00
Full implementations of < code class = "computeroutput" > < span class = "identifier" > prior_impl< / span > < / code > ,
< 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 >
2006-08-22 15:57:13 +00:00
are provided in the example code.
< / p >
< a name = "fusion.extension.implementing_the_intrinsic_functions_of_the_sequence" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1185084" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.implementing_the_intrinsic_functions_of_the_sequence" > Implementing
the intrinsic functions of the sequence< / a >
< / h3 >
< p >
In order that Fusion can correctly identify our sequence as a Fusion sequence,
2007-02-15 23:11:24 +00:00
we need to enable < code class = "computeroutput" > < span class = "identifier" > is_sequence< / span > < / code >
for our sequence type. As usual we just create an < code class = "computeroutput" > < span class = "identifier" > impl< / span > < / code >
2006-08-22 15:57:13 +00:00
type specialized for our sequence tag:
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > is_sequence_impl< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_sequence_tag< / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > T< / span > < span class = "special" > > < / span >
< 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 >
< span class = "special" > };< / span >
< / pre >
< p >
2007-02-15 23:11:24 +00:00
We've some similar formalities to complete, providing < code class = "computeroutput" > < span class = "identifier" > category_of_impl< / span > < / code >
so Fusion can correctly identify our sequence type, and < code class = "computeroutput" > < span class = "identifier" > is_view_impl< / span > < / code >
2006-08-22 15:57:13 +00:00
so Fusion can correctly identify our sequence as not being a < a href = "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
2007-02-15 23:11:24 +00:00
get < a href = "sequences/intrinsics/functions/begin.html" title = "begin" > < code class = "computeroutput" > < span class = "identifier" > begin< / span > < / code > < / a > working so that we can get an
2006-08-22 15:57:13 +00:00
iterator to start accessing the data in our sequence.
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > begin_impl< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_sequence_tag< / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Sequence< / span > < span class = "special" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span >
< span class = "special" > {< / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > typedef< / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_struct_iterator< / span > < span class = "special" > < < / span > < span class = "identifier" > Sequence< / span > < span class = "special" > ,< / span > < span class = "number" > 0< / span > < span class = "special" > > < / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
2006-08-22 15:57:13 +00:00
< span class = "keyword" > static< / span > < span class = "identifier" > type< / span >
< span class = "identifier" > call< / span > < span class = "special" > (< / span > < span class = "identifier" > Sequence< / span > < span class = "special" > & < / span > < span class = "identifier" > seq< / span > < span class = "special" > )< / span >
< span class = "special" > {< / span >
< span class = "keyword" > return< / span > < span class = "identifier" > type< / span > < span class = "special" > (< / span > < span class = "identifier" > seq< / span > < span class = "special" > );< / span >
< span class = "special" > }< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< / pre >
< p >
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
2007-02-15 23:11:24 +00:00
to the first element in the sequence. The implementation of < a href = "sequences/intrinsics/functions/end.html" title = "end" > < code class = "computeroutput" > < span class = "identifier" > end< / span > < / code > < / a > is very similar, and is provided
2006-08-22 15:57:13 +00:00
in the example code.
< / p >
< p >
For our < a href = "sequences/concepts/random_access_sequence.html" title = "Random
Access Sequence">Random
2007-02-15 23:11:24 +00:00
Access Sequence< / a > we will also need to implement < code class = "computeroutput" > < span class = "identifier" > size_impl< / span > < / code > ,
< code class = "computeroutput" > < span class = "identifier" > value_at_impl< / span > < / code > and < code class = "computeroutput" > < span class = "identifier" > at_impl< / span > < / code > .
2006-08-22 15:57:13 +00:00
< / p >
< a name = "fusion.extension.enabling_our_type_as_an_associative_container" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1185603" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.enabling_our_type_as_an_associative_container" > Enabling
our type as an associative container< / a >
< / h3 >
< p >
2007-02-15 23:11:24 +00:00
In order for < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code >
2006-08-22 15:57:13 +00:00
to serve as an associative container, we need to enable 3 lookup features,
2007-02-15 23:11:24 +00:00
< a href = "sequences/intrinsics/functions/at_key.html" title = "at_key" > < code class = "computeroutput" > < span class = "identifier" > at_key< / span > < / code > < / a > , < a href = "sequences/intrinsics/metafunctions/value_at_key.html" title = "value_at_key" > < code class = "computeroutput" > < span class = "identifier" > value_at_key< / span > < / code > < / a > and < a href = "sequences/intrinsics/functions/has_key.html" title = "has_key" > < code class = "computeroutput" > < span class = "identifier" > has_key< / span > < / code > < / a > . We also need to provide an
implementation of the < code class = "computeroutput" > < span class = "identifier" > is_associative< / span > < / code >
2006-08-22 15:57:13 +00:00
trait so that our sequence can be correctly identified as an associative container.
< / p >
< p >
2007-02-15 23:11:24 +00:00
To implement < code class = "computeroutput" > < span class = "identifier" > at_key_impl< / span > < / code > we
need to associate the < code class = "computeroutput" > < span class = "identifier" > fields< / span > < span class = "special" > ::< / span > < span class = "identifier" > age< / span > < / code > and
< code class = "computeroutput" > < span class = "identifier" > fields< / span > < span class = "special" > ::< / span > < span class = "identifier" > age< / span > < / code > types described in the < a href = "quick_start.html" title = "Quick Start" > Quick
Start< / a > guide with the appropriate members of < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code > .
2006-08-22 15:57:13 +00:00
Our implementation is as follows:
< / p >
< pre class = "programlisting" >
< span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2006-10-30 01:20:23 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > at_key_impl< / span > < span class = "special" > < < / span > < span class = "identifier" > example< / span > < span class = "special" > ::< / span > < span class = "identifier" > example_sequence_tag< / span > < span class = "special" > > < / span >
2006-08-22 15:57:13 +00:00
< span class = "special" > {< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / 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" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > ;< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Sequence< / span > < span class = "special" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / 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" > > < / span >
< span class = "special" > {< / span >
< 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" > < < / span >
< span class = "identifier" > is_const< / span > < span class = "special" > < < / span > < span class = "identifier" > Sequence< / span > < span class = "special" > > ,< / span >
< span class = "identifier" > std< / span > < span class = "special" > ::< / span > < span class = "identifier" > string< / span > < span class = "keyword" > const< / span > < span class = "special" > & ,< / span >
< span class = "identifier" > std< / span > < span class = "special" > ::< / span > < span class = "identifier" > string< / span > < span class = "special" > & > ::< / span > < span class = "identifier" > type< / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
< span class = "keyword" > static< / span > < span class = "identifier" > type< / span >
< span class = "identifier" > call< / span > < span class = "special" > (< / span > < span class = "identifier" > Sequence< / span > < span class = "special" > & < / span > < span class = "identifier" > seq< / span > < span class = "special" > )< / span >
< span class = "special" > {< / span >
< span class = "keyword" > return< / span > < span class = "identifier" > seq< / span > < span class = "special" > .< / span > < span class = "identifier" > name< / span > < span class = "special" > ;< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< span class = "keyword" > template< / span > < span class = "special" > < < / span > < span class = "keyword" > typename< / span > < span class = "identifier" > Sequence< / span > < span class = "special" > > < / span >
< span class = "keyword" > struct< / span > < span class = "identifier" > apply< / span > < span class = "special" > < < / 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" > > < / span >
< span class = "special" > {< / span >
< 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" > < < / span >
< span class = "identifier" > is_const< / span > < span class = "special" > < < / span > < span class = "identifier" > Sequence< / span > < span class = "special" > > ,< / span >
< span class = "keyword" > int< / span > < span class = "keyword" > const< / span > < span class = "special" > & ,< / span >
< span class = "keyword" > int< / span > < span class = "special" > & > ::< / span > < span class = "identifier" > type< / span > < span class = "identifier" > type< / span > < span class = "special" > ;< / span >
< span class = "keyword" > static< / span > < span class = "identifier" > type< / span >
< span class = "identifier" > call< / span > < span class = "special" > (< / span > < span class = "identifier" > Sequence< / span > < span class = "special" > & < / span > < span class = "identifier" > seq< / span > < span class = "special" > )< / span >
< span class = "special" > {< / span >
< span class = "keyword" > return< / span > < span class = "identifier" > seq< / span > < span class = "special" > .< / span > < span class = "identifier" > age< / span > < span class = "special" > ;< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< / pre >
< p >
Its all very similar to the implementations we've seen previously, such as
2007-02-15 23:11:24 +00:00
< 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
members by index or position, we are now selecting them using the types < 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 > . The
implementations of < code class = "computeroutput" > < span class = "identifier" > value_at_key_impl< / span > < / code >
and < code class = "computeroutput" > < span class = "identifier" > has_key_impl< / span > < / code > are equally
2006-08-22 15:57:13 +00:00
straightforward, and are provided in the example code, along with an implementation
2007-02-15 23:11:24 +00:00
of < code class = "computeroutput" > < span class = "identifier" > is_associative_impl< / span > < / code > .
2006-08-22 15:57:13 +00:00
< / p >
< a name = "fusion.extension.summary" > < / a > < h3 >
2007-02-15 23:11:24 +00:00
< a name = "id1186467" > < / a >
2006-08-22 15:57:13 +00:00
< a href = "extension.html#fusion.extension.summary" > Summary< / a >
< / h3 >
< p >
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 >
2007-02-15 23:11:24 +00:00
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 >
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
2006-08-22 15:57:13 +00:00
additional examples of the approach for a variety of types.
< / p >
< / div >
< table xmlns:rev = "http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width = "100%" > < tr >
< td align = "left" > < / td >
< td align = "right" > < small > Copyright <20> 2001-2005 Joel de Guzman, Dan Marsden< / small > < / td >
< / tr > < / table >
< hr >
< div class = "spirit-nav" >
2007-02-15 23:11:24 +00:00
< a accesskey = "p" href = "tuples/pairs.html" > < img src = "../images/prev.png" alt = "Prev" > < / a > < a accesskey = "u" href = "../index.html" > < img src = "../images/up.png" alt = "Up" > < / a > < a accesskey = "h" href = "../index.html" > < img src = "../images/home.png" alt = "Home" > < / a > < a accesskey = "n" href = "functional.html" > < img src = "../images/next.png" alt = "Next" > < / a >
2006-08-22 15:57:13 +00:00
< / div >
< / body >
< / html >