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