2007-11-06 12:13:52 +00:00
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=ISO-8859-1" >
< title > The Full Extension Mechanism</ title >
2007-11-07 03:46:23 +00:00
< link rel = "stylesheet" href = "../../../../../../doc/html/boostbook.css" type = "text/css" >
2009-02-22 06:27:12 +00:00
< meta name = "generator" content = "DocBook XSL Stylesheets V1.68.1" >
2007-11-06 12:13:52 +00:00
< link rel = "start" href = "../../index.html" title = "Chapter 1. Fusion 2.0" >
< link rel = "up" href = "../extension.html" title = "Extension" >
< link rel = "prev" href = "../extension.html" title = "Extension" >
< 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 >
2007-11-06 12:13:52 +00:00
< td align = "center" >< a href = "../../../../../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" >
< a accesskey = "p" href = "../extension.html" >< img src = "../../../../../../doc/html/images/prev.png" alt = "Prev" ></ a >< a accesskey = "u" href = "../extension.html" >< img src = "../../../../../../doc/html/images/up.png" alt = "Up" ></ a >< a accesskey = "h" href = "../../index.html" >< img src = "../../../../../../doc/html/images/home.png" alt = "Home" ></ a >< a accesskey = "n" href = "sequence_facade.html" >< img src = "../../../../../../doc/html/images/next.png" alt = "Next" ></ a >
</ div >
< div class = "section" lang = "en" >
< div class = "titlepage" >< div >< div >< h3 class = "title" >
< a name = "fusion.extension.ext_full" ></ a >< a href = "ext_full.html" title = " The Full Extension Mechanism" > The Full Extension Mechanism</ a ></ h3 ></ div ></ div ></ div >
< p >
The Fusion library is designed to be extensible, new sequences types can
2009-02-22 06:27:12 +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 >
< 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.ext_full.our_example" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1256502" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.our_example" > Our example</ a >
</ h4 >
< 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-02-22 06:27:12 +00:00
steps to enable < code class = "computeroutput" >< span class = "identifier" > example_struct</ span ></ code >
2007-11-06 12:13:52 +00:00
to serve as an < a href = "../sequence/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.ext_full.enabling_tag_dispatching" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1256758" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.enabling_tag_dispatching" > Enabling
Tag Dispatching</ a >
</ h4 >
< 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 >
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-02-22 06:27:12 +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-02-22 06:27:12 +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-02-22 06:27:12 +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 >
< a name = "fusion.extension.ext_full.designing_a_suitable_iterator" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1257308" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.designing_a_suitable_iterator" > Designing
a suitable iterator</ a >
</ h4 >
< 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-02-22 06:27:12 +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 >
< 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 >
2009-02-22 06:27: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
2007-11-06 12:13:52 +00:00
access to information we will need later in the implementation.
</ li >
< li >
2009-02-22 06:27: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 href = "../support/category_of.html" title = "category_of" >< code class = "computeroutput" >< span class = "identifier" > category_of</ span ></ code ></ a ></ code >
2007-11-06 12:13:52 +00:00
metafunction to establish the traversal category of the iterator.
</ li >
< li >
2009-02-22 06:27:12 +00:00
The constructor stores a reference to the < code class = "computeroutput" >< span class = "identifier" > example_struct</ span ></ code >
2007-11-06 12:13:52 +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
2009-02-22 06:27:12 +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 >
< a name = "fusion.extension.ext_full.a_first_couple_of_instructive_features" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1257892" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.a_first_couple_of_instructive_features" > A
first couple of instructive features</ a >
</ h4 >
< p >
2009-02-22 06:27:12 +00:00
To start with, we will get the < a 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-02-22 06:27:12 +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-02-22 06:27:12 +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 = "../iterator/metafunctions/value_of.html" title = "value_of" >< code class = "computeroutput" >< 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 >
< span class = "keyword" > struct</ span > < a href = "../iterator/metafunctions/value_of.html" title = "value_of" >< code class = "computeroutput" >< span class = "identifier" > value_of</ 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" > 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-02-22 06:27:12 +00:00
So < a href = "../iterator/metafunctions/value_of.html" title = "value_of" >< code class = "computeroutput" >< span class = "identifier" > value_of</ span ></ code ></ a >
2007-11-06 12:13:52 +00:00
uses < a 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
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-02-22 06:27:12 +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-02-22 06:27:12 +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 = "../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-02-22 06:27:12 +00:00
< span class = "keyword" > struct</ span > < a 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-02-22 06:27:12 +00:00
< a 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-02-22 06:27:12 +00:00
So again < a 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 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 = "../iterator/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 = "../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-02-22 06:27:12 +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-02-22 06:27:12 +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 >
< div class = "note" >< table border = "0" summary = "Note" >
< tr >
< td rowspan = "2" align = "center" valign = "top" width = "25" >< img alt = "[Note]" src = "../../../../../../doc/html/images/note.png" ></ td >
< th align = "left" > Note</ th >
</ tr >
2009-02-22 06:27:12 +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-02-22 06:27:12 +00:00
Fusion sequence, < a href = "../iterator/metafunctions/value_of.html" title = "value_of" >< code class = "computeroutput" >< span class = "identifier" > value_of</ span ></ code ></ a > and < a href = "../iterator/functions/deref.html" title = "deref" >< code class = "computeroutput" >< span class = "identifier" > deref</ span ></ code ></ a > illustrate all the signficant
2007-11-06 12:13:52 +00:00
concepts required. The remainder of the process is very repetitive, simply
2009-02-22 06:27:12 +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 > .
2007-11-06 12:13:52 +00:00
</ p ></ td ></ tr >
</ table ></ div >
< a name = "fusion.extension.ext_full.implementing_the_remaining_iterator_functionality" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1277403" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.implementing_the_remaining_iterator_functionality" > Implementing
the remaining iterator functionality</ a >
</ h4 >
< p >
2009-02-22 06:27:12 +00:00
Ok, now we have seen the way < a href = "../iterator/metafunctions/value_of.html" title = "value_of" >< code class = "computeroutput" >< span class = "identifier" > value_of</ span ></ code ></ a > and < a href = "../iterator/functions/deref.html" title = "deref" >< code class = "computeroutput" >< span class = "identifier" > deref</ span ></ code ></ a > work, everything else will
2007-11-06 12:13:52 +00:00
work in pretty much the same way. Lets start with forward iteration, by providing
2009-02-22 06:27:12 +00:00
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-02-22 06:27:12 +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-02-22 06:27:12 +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-02-22 06:27:12 +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-02-22 06:27:12 +00:00
We also need to provide a suitable < code class = "computeroutput" >< span class = "identifier" > equal_to_impl</ span ></ code >
2007-11-06 12:13:52 +00:00
so that iterators can be correctly compared. A < a href = "../iterator/concepts/bidirectional_iterator.html" title = "Bidirectional
Iterator" > Bidirectional
2009-02-22 06:27:12 +00:00
Iterator</ a > will also need an implementation of < code class = "computeroutput" >< span class = "identifier" > prior_impl</ span ></ code > .
2007-11-06 12:13:52 +00:00
For a < a href = "../iterator/concepts/random_access_iterator.html" title = "Random
Access Iterator" > Random
2009-02-22 06:27:12 +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
2007-11-06 12:13:52 +00:00
to be provided in order to satisfy the necessary complexity guarantees. As
our iterator is a < a href = "../iterator/concepts/random_access_iterator.html" title = "Random
Access Iterator" > Random
Access Iterator</ a > we will have to implement all of these functions.
</ p >
< p >
2009-02-22 06:27:12 +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 >
< a name = "fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1277977" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence" > Implementing
the intrinsic functions of the sequence</ a >
</ h4 >
< p >
In order that Fusion can correctly identify our sequence as a Fusion sequence,
2009-02-22 06:27:12 +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-02-22 06:27:12 +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 >
2007-11-06 12:13:52 +00:00
so Fusion can correctly identify our sequence as not being a < a href = "../view.html" title = "View" > View</ a >
type. Implementations are provide in the example code.
</ p >
< p >
Now we've completed some formalities, on to more interesting features. Lets
2009-02-22 06:27:12 +00:00
get < a 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-02-22 06:27:12 +00:00
to the first element in the sequence. The implementation of < a 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 >
For our < a href = "../sequence/concepts/random_access_sequence.html" title = "Random
Access Sequence" > Random
2009-02-22 06:27:12 +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 > .
2007-11-06 12:13:52 +00:00
</ p >
< a name = "fusion.extension.ext_full.enabling_our_type_as_an_associative_container" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1278512" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.enabling_our_type_as_an_associative_container" > Enabling
our type as an associative container</ a >
</ h4 >
< p >
2009-02-22 06:27:12 +00:00
In order for < code class = "computeroutput" >< span class = "identifier" > example_struct</ span ></ code >
2007-11-06 12:13:52 +00:00
to serve as an associative container, we need to enable 3 lookup features,
2009-02-22 06:27:12 +00:00
< a href = "../sequence/intrinsic/functions/at_key.html" title = "at_key" >< code class = "computeroutput" >< span class = "identifier" > at_key</ span ></ code ></ a > , < a 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 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 provide
an implementation of the < code class = "computeroutput" >< span class = "identifier" > is_associative</ span ></ code >
2007-11-06 12:13:52 +00:00
trait so that our sequence can be correctly identified as an associative
container.
</ p >
< p >
2009-02-22 06:27:12 +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 > .
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-02-22 06:27:12 +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-02-22 06:27:12 +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 > .
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
2007-11-06 12:13:52 +00:00
straightforward, and are provided in the example code, along with an implementation
2009-02-22 06:27:12 +00:00
of < code class = "computeroutput" >< span class = "identifier" > is_associative_impl</ span ></ code > .
2007-11-06 12:13:52 +00:00
</ p >
< a name = "fusion.extension.ext_full.summary" ></ a >< h4 >
2009-02-22 06:27:12 +00:00
< a name = "id1279401" ></ a >
2007-11-06 12:13:52 +00:00
< a href = "ext_full.html#fusion.extension.ext_full.summary" > Summary</ a >
</ h4 >
< 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 >
2009-02-22 06:27:12 +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 >
2007-11-14 10:17:09 +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" >
< a accesskey = "p" href = "../extension.html" >< img src = "../../../../../../doc/html/images/prev.png" alt = "Prev" ></ a >< a accesskey = "u" href = "../extension.html" >< img src = "../../../../../../doc/html/images/up.png" alt = "Up" ></ a >< a accesskey = "h" href = "../../index.html" >< img src = "../../../../../../doc/html/images/home.png" alt = "Home" ></ a >< a accesskey = "n" href = "sequence_facade.html" >< img src = "../../../../../../doc/html/images/next.png" alt = "Next" ></ a >
</ div >
</ body >
</ html >