2007-11-06 12:13:52 +00:00
< html >
< head >
2009-12-11 21:01:22 +00:00
< meta http-equiv = "Content-Type" content = "text/html; charset=US-ASCII" >
2009-09-25 00:21:53 +00:00
< title > The Full Extension Mechanism< / title >
2010-07-04 19:20:50 +00:00
< link rel = "stylesheet" href = "../../../../../../doc/src/boostbook.css" type = "text/css" >
< meta name = "generator" content = "DocBook XSL Stylesheets V1.75.2" >
2009-12-11 21:01:22 +00:00
< link rel = "home" href = "../../index.html" title = "Chapter 1. Fusion 2.0" >
2007-11-06 12:13:52 +00:00
< link rel = "up" href = "../extension.html" title = "Extension" >
2009-09-25 00:21:53 +00:00
< link rel = "prev" href = "../extension.html" title = "Extension" >
2007-11-06 12:13:52 +00:00
< link rel = "next" href = "sequence_facade.html" title = "Sequence Facade" >
< / head >
< body bgcolor = "white" text = "black" link = "#0000FF" vlink = "#840084" alink = "#0000FF" >
< table cellpadding = "2" width = "100%" > < tr >
< td valign = "top" > < img alt = "Boost C++ Libraries" width = "277" height = "86" src = "../../../../../../boost.png" > < / td >
2008-07-17 23:59:22 +00:00
< td align = "center" > < a href = "../../../../../../index.html" > Home< / a > < / td >
2010-07-04 19:20:50 +00:00
< td align = "center" > < a href = "../../../../../../libs/libraries.htm" > Libraries< / a > < / td >
2008-07-17 23:59:22 +00:00
< td align = "center" > < a href = "http://www.boost.org/users/people.html" > People< / a > < / td >
< td align = "center" > < a href = "http://www.boost.org/users/faq.html" > FAQ< / a > < / td >
2007-11-06 12:13:52 +00:00
< td align = "center" > < a href = "../../../../../../more/index.htm" > More< / a > < / td >
< / tr > < / table >
< hr >
< div class = "spirit-nav" >
2010-07-04 19:20:50 +00:00
< 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 >
2007-11-06 12:13:52 +00:00
< / div >
2010-06-03 08:29:23 +00:00
< div class = "section" >
2009-09-25 00:21:53 +00:00
< div class = "titlepage" > < div > < div > < h3 class = "title" >
< a name = "fusion.extension.ext_full" > < / a > < a class = "link" href = "ext_full.html" title = "The Full Extension Mechanism" > The Full Extension Mechanism< / a >
< / h3 > < / div > < / div > < / div >
2007-11-06 12:13:52 +00:00
< p >
The Fusion library is designed to be extensible, new sequences types can
2009-09-25 00:21:53 +00:00
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 > ,
< 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 >
2007-11-06 12:13:52 +00:00
sequences is entirely provided using the extension mechanism.
< / p >
< p >
The process for adding a new sequence type to Fusion is:
< / p >
2009-09-25 00:21:53 +00:00
< div class = "orderedlist" > < ol class = "orderedlist" type = "1" >
< li class = "listitem" >
2010-06-13 01:45:12 +00:00
Enable the < a class = "link" 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 >
2009-09-25 00:21:53 +00:00
< li class = "listitem" >
2010-06-13 01:45:12 +00:00
Design an iterator type for the sequence
< / li >
2009-09-25 00:21:53 +00:00
< li class = "listitem" >
2010-06-13 01:45:12 +00:00
Provide specialized behaviour for the intrinsic operations of the new
Fusion sequence
< / li >
2007-11-06 12:13:52 +00:00
< / ol > < / div >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.our_example" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1094078" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.our_example" > Our example< / a >
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
In order to illustrate enabling a new sequence type for use with Fusion,
we are going to use the type:
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > namespace< / span > < span class = "identifier" > example< / span >
2007-11-06 12:13:52 +00:00
< 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
2009-09-25 00:21:53 +00:00
steps to enable < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code >
to serve as an < a class = "link" href = "../sequence/concepts/associative_sequence.html" title = "Associative Sequence" > Associative
Sequence< / a > as described in the < a class = "link" href = "../quick_start.html" title = "Quick Start" > Quick
2007-11-06 12:13:52 +00:00
Start< / a > guide.
< / p >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.enabling_tag_dispatching" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1094282" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.enabling_tag_dispatching" > Enabling
2007-11-06 12:13:52 +00:00
Tag Dispatching< / a >
2009-09-25 00:21:53 +00:00
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
2009-09-25 00:21:53 +00:00
The Fusion extensibility mechanism uses < a class = "link" href = "../notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag
2007-11-06 12:13:52 +00:00
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 >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > namespace< / span > < span class = "identifier" > example< / span > < span class = "special" > {< / span >
2007-11-06 12:13:52 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > example_sequence_tag< / span > < span class = "special" > ;< / span > < span class = "comment" > // Only definition needed
< / span > < span class = "special" > }< / span >
< / pre >
< p >
2009-09-25 00:21:53 +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 >
2007-11-06 12:13:52 +00:00
metafunction to return our newly chosen tag type for operations involving
2009-09-25 00:21:53 +00:00
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 >
2007-11-06 12:13:52 +00:00
for our sequence type.
< / p >
2009-02-22 06:27:12 +00:00
< 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 >
2007-11-06 12:13:52 +00:00
< 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" > 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" > > < / span >
< 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 >
< 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 >
< 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 >
< span class = "special" > };< / span >
< span class = "special" > }}}< / span >
< / pre >
< p >
2009-09-25 00:21:53 +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 >
2007-11-06 12:13:52 +00:00
to provide tag support for groups of related types. This feature is not necessary
for our sequence, but for an example see the code in:
< / p >
2009-02-22 06:27:12 +00:00
< 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" > 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" > > < / span >
2007-11-06 12:13:52 +00:00
< 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" > include< / 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 >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.designing_a_suitable_iterator" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1094718" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.designing_a_suitable_iterator" > Designing
2007-11-06 12:13:52 +00:00
a suitable iterator< / a >
2009-09-25 00:21:53 +00:00
< / h5 >
2007-11-06 12:13:52 +00:00
< 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 >
2009-09-25 00:21:53 +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.
2007-11-06 12:13:52 +00:00
< / p >
2009-02-22 06:27:12 +00:00
< 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 >
2007-11-06 12:13:52 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > example_struct_iterator< / 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" > 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 >
< 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 >
< 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 >
< 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 >
2009-09-25 00:21:53 +00:00
< div class = "orderedlist" > < ol class = "orderedlist" type = "1" >
< li class = "listitem" >
2010-06-13 01:45:12 +00:00
The iterator is parameterized by the type it is iterating over, and the
index of the current element.
< / li >
2009-09-25 00:21:53 +00:00
< li class = "listitem" >
2010-06-13 01:45:12 +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
access to information we will need later in the implementation.
< / li >
2009-09-25 00:21:53 +00:00
< li class = "listitem" >
2010-06-13 01:45:12 +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 class = "link" href = "../support/category_of.html" title = "category_of" > < code class = "computeroutput" > < span class = "identifier" > category_of< / span > < / code > < / a > < / code >
metafunction to establish the traversal category of the iterator.
< / li >
2009-09-25 00:21:53 +00:00
< li class = "listitem" >
2010-06-13 01:45:12 +00:00
The constructor stores a reference to the < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code >
being iterated over.
< / li >
2007-11-06 12:13:52 +00:00
< / ol > < / div >
< p >
2009-09-25 00:21:53 +00:00
We also need to enable < a class = "link" href = "../notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag
2007-11-06 12:13:52 +00:00
dispatching< / em > < / span > < / a > for our iterator type, with another specialization
2009-09-25 00:21:53 +00:00
of < code class = "computeroutput" > < span class = "identifier" > traits< / span > < span class = "special" > ::< / span > < span class = "identifier" > tag_of< / span > < / code > .
2007-11-06 12:13:52 +00:00
< / p >
< p >
In isolation, the iterator implementation is pretty dry. Things should become
clearer as we add features to our implementation.
< / p >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.a_first_couple_of_instructive_features" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1095191" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.a_first_couple_of_instructive_features" > A
2007-11-06 12:13:52 +00:00
first couple of instructive features< / a >
2009-09-25 00:21:53 +00:00
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
2009-09-25 00:21:53 +00:00
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
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 >
2007-11-06 12:13:52 +00:00
template for our iterator's tag type.
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2007-11-06 12:13:52 +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 >
< 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 >
< 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 >
< 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 >
< 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 >
< 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
2009-09-25 00:21:53 +00:00
to provide the type of the 2 different members of < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code > ,
2007-11-06 12:13:52 +00:00
based on the index of the iterator.
< / p >
< p >
2009-09-25 00:21:53 +00:00
To understand how < code class = "computeroutput" > < span class = "identifier" > value_of_impl< / span > < / code >
2009-12-28 17:45:42 +00:00
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 > :
2007-11-06 12:13:52 +00:00
< / p >
2009-02-22 06:27:12 +00:00
< 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 >
2009-12-28 17:45:42 +00:00
< span class = "keyword" > struct< / span > < span class = "identifier" > value_of< / span >
2007-11-06 12:13:52 +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 >
< / pre >
< p >
2009-12-28 17:45:42 +00:00
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 >
uses < a class = "link" href = "../notes.html#fusion.notes.tag_dispatching" > < span class = "emphasis" > < em > tag dispatching< / em > < / span > < / a >
to select an < a href = "http://www.boost.org/libs/mpl/doc/refmanual/metafunction-class.html" target = "_top" > MPL
2007-11-06 12:13:52 +00:00
Metafunction Class< / a > to provide its functionality. You will notice
this pattern throughout the implementation of Fusion.
< / p >
< p >
Ok, lets enable dereferencing of our iterator. In this case we must provide
2009-09-25 00:21:53 +00:00
a suitable specialization of < code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code > .
2007-11-06 12:13:52 +00:00
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2007-11-06 12:13:52 +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 >
< 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 >
< 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 >
< 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 >
< 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 >
< 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 >
< 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 >
< 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 >
< 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 >
< 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" > age< / span > < span class = "special" > ;< / span >
< span class = "special" > }< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< span class = "special" > }< / span >
< / pre >
< p >
2009-09-25 00:21:53 +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 class = "link" href = "../iterator/functions/deref.html" title = "deref" > < code class = "computeroutput" > < span class = "identifier" > deref< / span > < / code > < / a > :
2007-11-06 12:13:52 +00:00
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > namespace< / span > < span class = "identifier" > result_of< / span >
2007-11-06 12:13:52 +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 >
2009-09-25 00:21:53 +00:00
< 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 >
2007-11-06 12:13:52 +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 >
< 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" > 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 >
2009-09-25 00:21:53 +00:00
< 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" > & < / span > < span class = "identifier" > i< / span > < span class = "special" > )< / span >
2007-11-06 12:13:52 +00:00
< span class = "special" > {< / span >
< 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 >
< span class = "special" > }< / span >
< / pre >
< p >
2009-09-25 00:21:53 +00:00
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
2009-12-28 17:45:42 +00:00
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
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
2007-11-06 12:13:52 +00:00
Metafunction Class< / a > .
< / p >
< p >
2009-09-25 00:21:53 +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 >
2007-11-06 12:13:52 +00:00
function, which returns a reference to the appropriate member of the underlying
2009-09-25 00:21:53 +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
2007-11-06 12:13:52 +00:00
is const.
< / p >
2010-06-03 08:29:23 +00:00
< div class = "note" > < table border = "0" summary = "Note" >
2007-11-06 12:13:52 +00:00
< tr >
2010-07-04 19:20:50 +00:00
< td rowspan = "2" align = "center" valign = "top" width = "25" > < img alt = "[Note]" src = "../../../../../../doc/src/images/note.png" > < / td >
2007-11-06 12:13:52 +00:00
< th align = "left" > Note< / th >
< / tr >
2009-09-25 00:21:53 +00:00
< tr > < td align = "left" valign = "top" > < p >
2007-11-06 12:13:52 +00:00
Although there is a fair amount of left to do to produce a fully fledged
2009-12-28 17:45:42 +00:00
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
concepts required. The remainder of the process is very repetitive, simply
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 > .
2007-11-06 12:13:52 +00:00
< / p > < / td > < / tr >
< / table > < / div >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.implementing_the_remaining_iterator_functionality" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1098058" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.implementing_the_remaining_iterator_functionality" > Implementing
2007-11-06 12:13:52 +00:00
the remaining iterator functionality< / a >
2009-09-25 00:21:53 +00:00
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
2009-12-28 17:45:42 +00:00
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
work in pretty much the same way. Lets start with forward iteration, by providing
a < code class = "computeroutput" > < span class = "identifier" > next_impl< / span > < / code > :
2007-11-06 12:13:52 +00:00
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2007-11-06 12:13:52 +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 >
< 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 >
< 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 >
< 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 >
< 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 >
< span class = "special" > }< / span >
< span class = "special" > };< / span >
< span class = "special" > };< / span >
< / pre >
< p >
2009-09-25 00:21:53 +00:00
This should be very familiar from our < code class = "computeroutput" > < span class = "identifier" > deref_impl< / span > < / code >
2007-11-06 12:13:52 +00:00
implementation, we will be using this approach again and again now. Our design
2009-09-25 00:21:53 +00:00
is simply to increment the < code class = "computeroutput" > < span class = "identifier" > index< / span > < / code >
2007-11-06 12:13:52 +00:00
counter to move on to the next element. The various other iterator manipulations
2009-09-25 00:21:53 +00:00
we need to perform will all just involve simple calculations with the < code class = "computeroutput" > < span class = "identifier" > index< / span > < / code > variables.
2007-11-06 12:13:52 +00:00
< / p >
< p >
2009-09-25 00:21:53 +00:00
We also need to provide a suitable < code class = "computeroutput" > < span class = "identifier" > equal_to_impl< / span > < / code >
so that iterators can be correctly compared. A < a class = "link" href = "../iterator/concepts/bidirectional_iterator.html" title = "Bidirectional Iterator" > Bidirectional
Iterator< / a > will also need an implementation of < code class = "computeroutput" > < span class = "identifier" > prior_impl< / span > < / code > .
For a < a class = "link" href = "../iterator/concepts/random_access_iterator.html" title = "Random Access Iterator" > Random
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
2007-11-06 12:13:52 +00:00
to be provided in order to satisfy the necessary complexity guarantees. As
2009-09-25 00:21:53 +00:00
our iterator is a < a class = "link" href = "../iterator/concepts/random_access_iterator.html" title = "Random Access Iterator" > Random
2007-11-06 12:13:52 +00:00
Access Iterator< / a > we will have to implement all of these functions.
< / p >
< p >
2009-09-25 00:21:53 +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 >
2007-11-06 12:13:52 +00:00
are provided in the example code.
< / p >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1098502" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence" > Implementing
2007-11-06 12:13:52 +00:00
the intrinsic functions of the sequence< / a >
2009-09-25 00:21:53 +00:00
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
In order that Fusion can correctly identify our sequence as a Fusion sequence,
2009-09-25 00:21:53 +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 >
2007-11-06 12:13:52 +00:00
type specialized for our sequence tag:
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2007-11-06 12:13:52 +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 >
< 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 >
2009-09-25 00:21:53 +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 >
so Fusion can correctly identify our sequence as not being a < a class = "link" href = "../view.html" title = "View" > View< / a >
2007-11-06 12:13:52 +00:00
type. Implementations are provide in the example code.
< / p >
< p >
Now we've completed some formalities, on to more interesting features. Lets
2009-09-25 00:21:53 +00:00
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
2007-11-06 12:13:52 +00:00
an iterator to start accessing the data in our sequence.
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2007-11-06 12:13:52 +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 >
< 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 = "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 >
< 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
2009-09-25 00:21:53 +00:00
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
2007-11-06 12:13:52 +00:00
in the example code.
< / p >
< p >
2009-09-25 00:21:53 +00:00
For our < a class = "link" href = "../sequence/concepts/random_access_sequence.html" title = "Random Access Sequence" > Random
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 > .
2007-11-06 12:13:52 +00:00
< / p >
2009-12-28 17:45:42 +00:00
< a name = "fusion.extension.ext_full.enabling_our_type_as_an_associative_sequence" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1098914" > < / a >
2009-12-28 17:45:42 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.enabling_our_type_as_an_associative_sequence" > Enabling
our type as an associative sequence< / a >
2009-09-25 00:21:53 +00:00
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
2009-09-25 00:21:53 +00:00
In order for < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code >
2009-12-28 17:45:42 +00:00
to serve as an associative forward sequence, we need to adapt the traversal
category of our sequence and our iterator accordingly and enable 3 intrinsic
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 > , < a class = "link" href = "../sequence/intrinsic/metafunctions/value_at_key.html" title = "value_at_key" > < code class = "computeroutput" > < span class = "identifier" > value_at_key< / span > < / code > < / a > 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 > . 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 > .
2007-11-06 12:13:52 +00:00
< / p >
< p >
2009-09-25 00:21:53 +00:00
To implement < code class = "computeroutput" > < span class = "identifier" > at_key_impl< / span > < / code >
2009-12-28 17:45:42 +00:00
we need to associate the < 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 > types described in the < a class = "link" href = "../quick_start.html" title = "Quick Start" > Quick
2009-09-25 00:21:53 +00:00
Start< / a > guide with the appropriate members of < code class = "computeroutput" > < span class = "identifier" > example_struct< / span > < / code > .
2007-11-06 12:13:52 +00:00
Our implementation is as follows:
< / p >
2009-02-22 06:27:12 +00:00
< pre class = "programlisting" > < span class = "keyword" > template< / span > < span class = "special" > < > < / span >
2007-11-06 12:13:52 +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 >
< 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
2009-09-25 00:21:53 +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
2007-11-06 12:13:52 +00:00
members by index or position, we are now selecting them using the types
2009-09-25 00:21:53 +00:00
< 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 > .
2009-12-28 17:45:42 +00:00
The implementations of the other functions are equally straightforward, and
are provided in the example code.
2007-11-06 12:13:52 +00:00
< / p >
2009-09-25 00:21:53 +00:00
< a name = "fusion.extension.ext_full.summary" > < / a > < h5 >
2010-07-08 17:25:24 +00:00
< a name = "id1100174" > < / a >
2009-09-25 00:21:53 +00:00
< a class = "link" href = "ext_full.html#fusion.extension.ext_full.summary" > Summary< / a >
< / h5 >
2007-11-06 12:13:52 +00:00
< p >
We've now worked through the entire process for adding a new random access
2009-12-28 17:45:42 +00:00
sequence and we've also enabled our type to serve as an associative sequence.
2007-11-06 12:13:52 +00:00
The implementation was slightly longwinded, but followed a simple repeating
pattern.
< / p >
< p >
2009-09-25 00:21:53 +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
2007-11-06 12:13:52 +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 >
2009-12-11 21:01:22 +00:00
< td align = "right" > < div class = "copyright-footer" > Copyright © 2001-2007 Joel de Guzman, Dan Marsden, Tobias
2007-11-07 02:12:28 +00:00
Schwinger< p >
Distributed under the Boost Software License, Version 1.0. (See accompanying
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 > )
2007-11-14 10:17:09 +00:00
< / p >
< / div > < / td >
2007-11-06 12:13:52 +00:00
< / tr > < / table >
< hr >
< div class = "spirit-nav" >
2010-07-04 19:20:50 +00:00
< 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 >
2007-11-06 12:13:52 +00:00
< / div >
< / body >
< / html >