forked from boostorg/fusion
https://svn.boost.org/svn/boost/trunk ........ r41077 | troyer | 2007-11-13 23:00:02 -0800 (Tue, 13 Nov 2007) | 1 line Added support for std::complex to serialization ........ r41078 | joaquin | 2007-11-13 23:09:29 -0800 (Tue, 13 Nov 2007) | 1 line added missing include ........ r41079 | djowel | 2007-11-14 02:13:51 -0800 (Wed, 14 Nov 2007) | 1 line adjust to compensate for lack of <small> tag. ........ r41080 | djowel | 2007-11-14 02:17:09 -0800 (Wed, 14 Nov 2007) | 1 line refresh docs ........ r41081 | djowel | 2007-11-14 02:23:23 -0800 (Wed, 14 Nov 2007) | 1 line refresh docs ........ r41082 | djowel | 2007-11-14 02:24:21 -0800 (Wed, 14 Nov 2007) | 1 line refresh docs ........ r41083 | anthonyw | 2007-11-14 03:08:09 -0800 (Wed, 14 Nov 2007) | 1 line ignore and join all threads in group on exception ........ r41084 | anthonyw | 2007-11-14 03:56:53 -0800 (Wed, 14 Nov 2007) | 1 line interrupt and join all threads in a group if an exception is thrown during a test ........ r41086 | johnmaddock | 2007-11-14 04:14:19 -0800 (Wed, 14 Nov 2007) | 1 line Merged changes from the Sandbox to Trunk. ........ r41087 | anthonyw | 2007-11-14 04:17:41 -0800 (Wed, 14 Nov 2007) | 1 line interrupt and join all threads in a group if an exception is thrown during a test ........ r41088 | johnmaddock | 2007-11-14 04:41:32 -0800 (Wed, 14 Nov 2007) | 1 line Added WinCE workaround. ........ r41089 | johnmaddock | 2007-11-14 05:03:15 -0800 (Wed, 14 Nov 2007) | 1 line Catch exceptions thrown from thread creation. ........ r41090 | anthonyw | 2007-11-14 06:49:58 -0800 (Wed, 14 Nov 2007) | 1 line fixes for pthread implementation ........ r41091 | bemandawes | 2007-11-14 07:50:43 -0800 (Wed, 14 Nov 2007) | 1 line Replace old docs with excerpts from http://article.gmane.org/gmane.comp.lib.boost.testing/5020 ........ r41093 | eric_niebler | 2007-11-14 08:36:15 -0800 (Wed, 14 Nov 2007) | 1 line fix support for segmented iteration ........ r41094 | dave | 2007-11-14 09:37:55 -0800 (Wed, 14 Nov 2007) | 3 lines Update command-prompt instructions per http://news.gmane.org/find-root.php?message_id=%3cfhcrem%24c4%241%40ger.gmane.org%3e ........ r41095 | bemandawes | 2007-11-14 12:05:30 -0800 (Wed, 14 Nov 2007) | 1 line Bring docs more in line with reality:-) ........ r41097 | hljin | 2007-11-14 18:07:53 -0800 (Wed, 14 Nov 2007) | 1 line GIL: removed the example directory from the documentation as it is a duplication and re-directed the Doxygen documentation to a local copy (to be submitted next) ........ r41098 | hljin | 2007-11-14 18:30:13 -0800 (Wed, 14 Nov 2007) | 1 line GIL: added a local copy of the Doxygen documentation ........ r41099 | hljin | 2007-11-14 18:32:04 -0800 (Wed, 14 Nov 2007) | 1 line GIL: added a local copy of the Doxygen documentation (second batch) ........ r41100 | chris_kohlhoff | 2007-11-14 22:19:04 -0800 (Wed, 14 Nov 2007) | 6 lines Try to fix an order-of-initialisation problem with error_category references. The symptom, which only occurs in some applications, is a crash due to a dereference of a null pointer. The exact conditions under which the problem occurs are not fully understood, so this fix is probably more paranoid than necessary. ........ r41102 | jhunold | 2007-11-14 23:04:24 -0800 (Wed, 14 Nov 2007) | 1 line Suppress msvc "deprecated" warnings. ........ r41103 | johnmaddock | 2007-11-15 01:52:26 -0800 (Thu, 15 Nov 2007) | 1 line Fix some compiler warnings when building with the Intel and aCC compilers. ........ r41104 | garcia | 2007-11-15 04:50:48 -0800 (Thu, 15 Nov 2007) | 2 lines John Torjo is reviewing the X-files. ........ r41105 | hkaiser | 2007-11-15 05:27:24 -0800 (Thu, 15 Nov 2007) | 1 line Suppressed more warnings during build of Wave. ........ r41106 | bemandawes | 2007-11-15 06:36:40 -0800 (Thu, 15 Nov 2007) | 1 line GetUserDefaultUILanguage isn't present for Cygwin, so disable use ........ r41107 | bemandawes | 2007-11-15 07:20:27 -0800 (Thu, 15 Nov 2007) | 1 line Get rid of .cvsignore files ........ r41108 | eric_niebler | 2007-11-15 08:06:22 -0800 (Thu, 15 Nov 2007) | 1 line fix typo ........ r41110 | grafik | 2007-11-15 08:58:21 -0800 (Thu, 15 Nov 2007) | 1 line Fix building of multiple regression tools at once. ........ r41111 | gmelquio | 2007-11-15 09:52:31 -0800 (Thu, 15 Nov 2007) | 1 line Fixed documentation typo. ........ r41113 | grafik | 2007-11-15 10:56:43 -0800 (Thu, 15 Nov 2007) | 1 line Switch intel-win32 to use static multi thread runtime since the single thread static runtime is no longer available. (fixes #1287) ........ r41114 | andreas_huber69 | 2007-11-15 11:22:12 -0800 (Thu, 15 Nov 2007) | 1 line Added new FAQ item suggested by Chris Paulse. ........ r41116 | guwi17 | 2007-11-15 12:52:37 -0800 (Thu, 15 Nov 2007) | 4 lines This patch now lets the Sun compiler work for most of uBLAS. 'test4' is now failing. Too avoid other compilers complaining about missing return values in some functions where exceptions are thrown, code was added so an arbitatry were chosen. ........ r41117 | danmarsden | 2007-11-15 13:15:47 -0800 (Thu, 15 Nov 2007) | 1 line removing failing test on EDG compilers ........ r41118 | grafik | 2007-11-15 14:05:15 -0800 (Thu, 15 Nov 2007) | 1 line Remove redundant reference to system library. It causes double linking when used indirectly through filesystem. Which can lead to double linking incompatible variants when a specific filesystem variant is requested. ........ r41119 | grafik | 2007-11-15 14:05:22 -0800 (Thu, 15 Nov 2007) | 1 line Oops, forgot we need to use the root boost project settings when building. ........ [SVN r41141]
546 lines
51 KiB
HTML
546 lines
51 KiB
HTML
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||
<title> The Full Extension Mechanism</title>
|
||
<link rel="stylesheet" href="../../../../../../doc/html/boostbook.css" type="text/css">
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||
<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>
|
||
<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>
|
||
</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
|
||
easily be added. In fact, the library support for <tt class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>,
|
||
<tt class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></tt> and <a href="http://www.boost.org/libs/mpl/index.html" target="_top">MPL</a>
|
||
sequences is entirely provided using the extension mechanism.
|
||
</p>
|
||
<p>
|
||
The process for adding a new sequence type to Fusion is:
|
||
</p>
|
||
<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>
|
||
<a name="id640115"></a>
|
||
<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>
|
||
<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 to enable <tt class="computeroutput"><span class="identifier">example_struct</span></tt>
|
||
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>
|
||
<a name="id640404"></a>
|
||
<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>
|
||
<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_sequence_tag</span><span class="special">;</span> <span class="comment">// Only definition needed
|
||
</span><span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
Next we need to enable the <tt class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></tt>
|
||
metafunction to return our newly chosen tag type for operations involving
|
||
our sequence. This is done by specializing <tt class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></tt>
|
||
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>
|
||
<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>
|
||
<tt class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></tt> also has a second template argument,
|
||
that can be used in conjuction with <tt class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span></tt>
|
||
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>
|
||
<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>
|
||
<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>
|
||
<a name="id641030"></a>
|
||
<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>
|
||
We will use a simple design, in which the 2 members of <tt class="computeroutput"><span class="identifier">example_struct</span></tt>
|
||
are given numbered indices, 0 for <tt class="computeroutput"><span class="identifier">name</span></tt>
|
||
and 1 for <tt class="computeroutput"><span class="identifier">age</span></tt> respectively.
|
||
</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>
|
||
<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>
|
||
The typedefs <tt class="computeroutput"><span class="identifier">struct_type</span></tt>
|
||
and <tt class="computeroutput"><span class="identifier">index</span></tt> provide convenient
|
||
access to information we will need later in the implementation.
|
||
</li>
|
||
<li>
|
||
The typedef <tt class="computeroutput"><span class="identifier">category</span></tt> allows
|
||
the <tt class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><a href="../support/category_of.html" title="category_of"><tt class="computeroutput"><span class="identifier">category_of</span></tt></a></tt>
|
||
metafunction to establish the traversal category of the iterator.
|
||
</li>
|
||
<li>
|
||
The constructor stores a reference to the <tt class="computeroutput"><span class="identifier">example_struct</span></tt>
|
||
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
|
||
of <tt class="computeroutput"><span class="identifier">traits</span><span class="special">::</span><span class="identifier">tag_of</span></tt>.
|
||
</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>
|
||
<a name="id641690"></a>
|
||
<a href="ext_full.html#fusion.extension.ext_full.a_first_couple_of_instructive_features">A
|
||
first couple of instructive features</a>
|
||
</h4>
|
||
<p>
|
||
To start with, we will get the <a href="../iterator/metafunctions/value_of.html" title="value_of"><tt class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_of</span></tt></a> metafunction working. To
|
||
do this, we provide a specialization of the <tt 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></tt>
|
||
template for our iterator's tag type.
|
||
</p>
|
||
<pre class="programlisting">
|
||
<span class="keyword">template</span><span class="special"><></span>
|
||
<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
|
||
to provide the type of the 2 different members of <tt class="computeroutput"><span class="identifier">example_struct</span></tt>,
|
||
based on the index of the iterator.
|
||
</p>
|
||
<p>
|
||
To understand how <tt class="computeroutput"><span class="identifier">value_of_impl</span></tt>
|
||
is used by the library we will look at the implementation of <a href="../iterator/metafunctions/value_of.html" title="value_of"><tt class="computeroutput"><span class="identifier">value_of</span></tt></a>:
|
||
</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>
|
||
<span class="keyword">struct</span> <a href="../iterator/metafunctions/value_of.html" title="value_of"><tt class="computeroutput"><span class="identifier">value_of</span></tt></a>
|
||
<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>
|
||
So <a href="../iterator/metafunctions/value_of.html" title="value_of"><tt class="computeroutput"><span class="identifier">value_of</span></tt></a>
|
||
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
|
||
a suitable specialization of <tt class="computeroutput"><span class="identifier">deref_impl</span></tt>.
|
||
</p>
|
||
<pre class="programlisting">
|
||
<span class="keyword">template</span><span class="special"><></span>
|
||
<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>
|
||
The use of <tt class="computeroutput"><span class="identifier">deref_impl</span></tt> is
|
||
very similar to that of <tt class="computeroutput"><span class="identifier">value_of_impl</span></tt>,
|
||
but it also provides some runtime functionality this time via the <tt class="computeroutput"><span class="identifier">call</span></tt> static member function. To see how
|
||
<tt class="computeroutput"><span class="identifier">deref_impl</span></tt> is used, lets
|
||
have a look at the implementation of <a href="../iterator/functions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">deref</span></tt></a>:
|
||
</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>
|
||
<span class="keyword">struct</span> <a href="../iterator/functions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">deref</span></tt></a>
|
||
<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>
|
||
<a href="../iterator/functions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">deref</span></tt></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>
|
||
<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>
|
||
So again <a href="../iterator/metafunctions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">deref</span></tt></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"><tt class="computeroutput"><span class="identifier">value_of</span></tt></a> implementation. The runtime
|
||
functionality used by <a href="../iterator/functions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">deref</span></tt></a> is provided by the <tt class="computeroutput"><span class="identifier">call</span></tt> static function of the selected <a href="http://www.boost.org/libs/mpl/doc/refmanual/metafunction-class.html" target="_top">MPL
|
||
Metafunction Class</a>.
|
||
</p>
|
||
<p>
|
||
The actual implementation of <tt class="computeroutput"><span class="identifier">deref_impl</span></tt>
|
||
is slightly more complex than that of <tt class="computeroutput"><span class="identifier">value_of_impl</span></tt>.
|
||
We also need to implement the <tt class="computeroutput"><span class="identifier">call</span></tt>
|
||
function, which returns a reference to the appropriate member of the underlying
|
||
sequence. We also require a little bit of metaprogramming to return <tt class="computeroutput"><span class="keyword">const</span></tt> references if the underlying sequence
|
||
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>
|
||
<tr><td colspan="2" align="left" valign="top"><p>
|
||
Although there is a fair amount of left to do to produce a fully fledged
|
||
Fusion sequence, <a href="../iterator/metafunctions/value_of.html" title="value_of"><tt class="computeroutput"><span class="identifier">value_of</span></tt></a> and <a href="../iterator/functions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">deref</span></tt></a> illustrate all the signficant
|
||
concepts required. The remainder of the process is very repetitive, simply
|
||
requiring implementation of a suitable <tt class="computeroutput"><span class="identifier">xxxx_impl</span></tt>
|
||
for each feature <tt class="computeroutput"><span class="identifier">xxxx</span></tt>.
|
||
</p></td></tr>
|
||
</table></div>
|
||
<a name="fusion.extension.ext_full.implementing_the_remaining_iterator_functionality"></a><h4>
|
||
<a name="id644002"></a>
|
||
<a href="ext_full.html#fusion.extension.ext_full.implementing_the_remaining_iterator_functionality">Implementing
|
||
the remaining iterator functionality</a>
|
||
</h4>
|
||
<p>
|
||
Ok, now we have seen the way <a href="../iterator/metafunctions/value_of.html" title="value_of"><tt class="computeroutput"><span class="identifier">value_of</span></tt></a> and <a href="../iterator/functions/deref.html" title="deref"><tt class="computeroutput"><span class="identifier">deref</span></tt></a> work, everything else will
|
||
work in pretty much the same way. Lets start with forward iteration, by providing
|
||
a <tt class="computeroutput"><span class="identifier">next_impl</span></tt>:
|
||
</p>
|
||
<pre class="programlisting">
|
||
<span class="keyword">template</span><span class="special"><></span>
|
||
<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>
|
||
This should be very familiar from our <tt class="computeroutput"><span class="identifier">deref_impl</span></tt>
|
||
implementation, we will be using this approach again and again now. Our design
|
||
is simply to increment the <tt class="computeroutput"><span class="identifier">index</span></tt>
|
||
counter to move on to the next element. The various other iterator manipulations
|
||
we need to perform will all just involve simple calculations with the <tt class="computeroutput"><span class="identifier">index</span></tt> variables.
|
||
</p>
|
||
<p>
|
||
We also need to provide a suitable <tt class="computeroutput"><span class="identifier">equal_to_impl</span></tt>
|
||
so that iterators can be correctly compared. A <a href="../iterator/concepts/bidirectional_iterator.html" title="Bidirectional
|
||
Iterator">Bidirectional
|
||
Iterator</a> will also need an implementation of <tt class="computeroutput"><span class="identifier">prior_impl</span></tt>.
|
||
For a <a href="../iterator/concepts/random_access_iterator.html" title="Random
|
||
Access Iterator">Random
|
||
Access Iterator</a> <tt class="computeroutput"><span class="identifier">distance_impl</span></tt>
|
||
and <tt class="computeroutput"><span class="identifier">advance_impl</span></tt> also need
|
||
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>
|
||
Full implementations of <tt class="computeroutput"><span class="identifier">prior_impl</span></tt>,
|
||
<tt class="computeroutput"><span class="identifier">advance_impl</span></tt>, <tt class="computeroutput"><span class="identifier">distance_impl</span></tt> and <tt class="computeroutput"><span class="identifier">equal_to_impl</span></tt>
|
||
are provided in the example code.
|
||
</p>
|
||
<a name="fusion.extension.ext_full.implementing_the_intrinsic_functions_of_the_sequence"></a><h4>
|
||
<a name="id644655"></a>
|
||
<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,
|
||
we need to enable <tt class="computeroutput"><span class="identifier">is_sequence</span></tt>
|
||
for our sequence type. As usual we just create an <tt class="computeroutput"><span class="identifier">impl</span></tt>
|
||
type specialized for our sequence tag:
|
||
</p>
|
||
<pre class="programlisting">
|
||
<span class="keyword">template</span><span class="special"><></span>
|
||
<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>
|
||
We've some similar formalities to complete, providing <tt class="computeroutput"><span class="identifier">category_of_impl</span></tt>
|
||
so Fusion can correctly identify our sequence type, and <tt class="computeroutput"><span class="identifier">is_view_impl</span></tt>
|
||
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
|
||
get <a href="../sequence/intrinsic/functions/begin.html" title="begin"><tt class="computeroutput"><span class="identifier">begin</span></tt></a> working so that we can get
|
||
an iterator to start accessing the data in our sequence.
|
||
</p>
|
||
<pre class="programlisting">
|
||
<span class="keyword">template</span><span class="special"><></span>
|
||
<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
|
||
to the first element in the sequence. The implementation of <a href="../sequence/intrinsic/functions/end.html" title="end"><tt class="computeroutput"><span class="identifier">end</span></tt></a> is very similar, and is provided
|
||
in the example code.
|
||
</p>
|
||
<p>
|
||
For our <a href="../sequence/concepts/random_access_sequence.html" title="Random
|
||
Access Sequence">Random
|
||
Access Sequence</a> we will also need to implement <tt class="computeroutput"><span class="identifier">size_impl</span></tt>,
|
||
<tt class="computeroutput"><span class="identifier">value_at_impl</span></tt> and <tt class="computeroutput"><span class="identifier">at_impl</span></tt>.
|
||
</p>
|
||
<a name="fusion.extension.ext_full.enabling_our_type_as_an_associative_container"></a><h4>
|
||
<a name="id645263"></a>
|
||
<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>
|
||
In order for <tt class="computeroutput"><span class="identifier">example_struct</span></tt>
|
||
to serve as an associative container, we need to enable 3 lookup features,
|
||
<a href="../sequence/intrinsic/functions/at_key.html" title="at_key"><tt class="computeroutput"><span class="identifier">at_key</span></tt></a>, <a href="../sequence/intrinsic/metafunctions/value_at_key.html" title="value_at_key"><tt class="computeroutput"><span class="identifier">value_at_key</span></tt></a> and <a href="../sequence/intrinsic/functions/has_key.html" title="has_key"><tt class="computeroutput"><span class="identifier">has_key</span></tt></a>. We also need to provide
|
||
an implementation of the <tt class="computeroutput"><span class="identifier">is_associative</span></tt>
|
||
trait so that our sequence can be correctly identified as an associative
|
||
container.
|
||
</p>
|
||
<p>
|
||
To implement <tt class="computeroutput"><span class="identifier">at_key_impl</span></tt>
|
||
we need to associate the <tt class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">age</span></tt> and
|
||
<tt class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">age</span></tt> types described in the <a href="../quick_start.html" title="Quick Start">Quick
|
||
Start</a> guide with the appropriate members of <tt class="computeroutput"><span class="identifier">example_struct</span></tt>.
|
||
Our implementation is as follows:
|
||
</p>
|
||
<pre class="programlisting">
|
||
<span class="keyword">template</span><span class="special"><></span>
|
||
<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
|
||
<tt class="computeroutput"><span class="identifier">deref_impl</span></tt> and <tt class="computeroutput"><span class="identifier">value_of_impl</span></tt>. Instead of identifying the
|
||
members by index or position, we are now selecting them using the types
|
||
<tt class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">name</span></tt> and <tt class="computeroutput"><span class="identifier">fields</span><span class="special">::</span><span class="identifier">age</span></tt>.
|
||
The implementations of <tt class="computeroutput"><span class="identifier">value_at_key_impl</span></tt>
|
||
and <tt class="computeroutput"><span class="identifier">has_key_impl</span></tt> are equally
|
||
straightforward, and are provided in the example code, along with an implementation
|
||
of <tt class="computeroutput"><span class="identifier">is_associative_impl</span></tt>.
|
||
</p>
|
||
<a name="fusion.extension.ext_full.summary"></a><h4>
|
||
<a name="id646271"></a>
|
||
<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>
|
||
The support for <tt class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>, <a href="http://www.boost.org/libs/mpl/index.html" target="_top">MPL</a>
|
||
sequences, and <tt class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></tt> all use the same approach, and provide
|
||
additional examples of the approach for a variety of types.
|
||
</p>
|
||
</div>
|
||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||
<td align="left"></td>
|
||
<td align="right"><div class="copyright-footer">Copyright © 2001-2007 Joel de Guzman, Dan Marsden, Tobias
|
||
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>)
|
||
</p>
|
||
</div></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>
|
||
</body>
|
||
</html>
|