diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /doc/html/proto | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'doc/html/proto')
-rwxr-xr-x | doc/html/proto/appendices.html | 658 | ||||
-rwxr-xr-x | doc/html/proto/reference.html | 2052 | ||||
-rwxr-xr-x | doc/html/proto/users_guide.html | 10881 |
3 files changed, 13591 insertions, 0 deletions
diff --git a/doc/html/proto/appendices.html b/doc/html/proto/appendices.html new file mode 100755 index 0000000000..66cb99de85 --- /dev/null +++ b/doc/html/proto/appendices.html @@ -0,0 +1,658 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Appendices</title> +<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> +<link rel="up" href="../proto.html" title="Chapter 20. Boost.Proto"> +<link rel="prev" href="../Transform.html" title="Concept Transform"> +<link rel="next" href="../boost_random.html" title="Chapter 21. Boost.Random"> +</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.html">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../Transform.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../boost_random.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="proto.appendices"></a><a class="link" href="appendices.html" title="Appendices">Appendices</a> +</h2></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.release_notes">Appendix A: Release + Notes</a></span></dt> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.history">Appendix B: History</a></span></dt> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.rationale">Appendix C: Rationale</a></span></dt> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.implementation">Appendix D: Implementation + Notes</a></span></dt> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.acknowledgements">Appendix E: + Acknowledgements</a></span></dt> +</dl></div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.appendices.release_notes"></a><a class="link" href="appendices.html#boost_proto.appendices.release_notes" title="Appendix A: Release Notes">Appendix A: Release + Notes</a> +</h3></div></div></div> +<h5> +<a name="boost_proto.appendices.release_notes.h0"></a> + <span><a name="boost_proto.appendices.release_notes.boost_1_44"></a></span><a class="link" href="appendices.html#boost_proto.appendices.release_notes.boost_1_44">Boost + 1.44</a> + </h5> +<p> + <span class="bold"><strong>Behavior Change: proto::and_<></strong></span> + </p> +<p> + In Boost 1.44, the behavior of <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_<></a></code> + as a transform changed. Previously, it only applied the transform associated + with the last grammar in the set. Now, it applies all the transforms but + only returns the result of the last. That makes it behave like C++'s comma + operator. For example, a grammar such as: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">and_</span><span class="special"><</span> <span class="identifier">G0</span><span class="special">,</span> <span class="identifier">G1</span><span class="special">,</span> <span class="identifier">G2</span> <span class="special">></span> +</pre> +<p> + when evaluated with an expression <code class="computeroutput"><span class="identifier">e</span></code> + now behaves like this: + </p> +<pre class="programlisting"><span class="special">(</span><span class="identifier">G0</span><span class="special">()(</span><span class="identifier">e</span><span class="special">),</span> <span class="identifier">G1</span><span class="special">()(</span><span class="identifier">e</span><span class="special">),</span> <span class="identifier">G2</span><span class="special">()(</span><span class="identifier">e</span><span class="special">))</span> +</pre> +<p> + <span class="bold"><strong>Behavior Change: proto::as_expr() and proto::as_child()</strong></span> + </p> +<p> + The functions <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + are used to guarantee that an object is a Proto expression by turning it + into one if it is not already, using an optionally specified domain. In previous + releases, when these functions were passed a Proto expression in a domain + different to the one specified, they would apply the specified domain's generator, + resulting in a twice-wrapped expression. This behavior was surprising to + some users. + </p> +<p> + The new behavior of these two functions is to always leave Proto expressions + alone, regardless of the expressions' domains. + </p> +<p> + <span class="bold"><strong>Behavior Change: proto::(pod_)generator<> and + proto::basic_expr<></strong></span> + </p> +<p> + Users familiar with Proto's extension mechanism have probably used either + <code class="computeroutput"><a class="link" href="../boost/proto/generator.html" title="Struct template generator">proto::generator<></a></code> or <code class="computeroutput"><a class="link" href="../boost/proto/pod_generator.html" title="Struct template pod_generator">proto::pod_generator<></a></code> + with a wrapper template when defining their domain. In the past, Proto would + instantiate your wrapper template with instances of <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code>. + In Boost 1.44, Proto now instantiates your wrapper template with instances + of a new type: <code class="computeroutput"><a class="link" href="../boost/proto/basic_expr.html" title="Struct template basic_expr">proto::basic_expr<></a></code>. + </p> +<p> + For instance: + </p> +<pre class="programlisting"><span class="comment">// An expression wrapper</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_expr_wrapper</span><span class="special">;</span> + +<span class="comment">// A domain</span> +<span class="keyword">struct</span> <span class="identifier">my_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span> <span class="identifier">my_expr_wrapper</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">class</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_expr_wrapper</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">my_expr_wrapper</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">my_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="comment">// Before 1.44, Expr was an instance of proto::expr<></span> + <span class="comment">// In 1.44, Expr is an instance of proto::basic_expr<></span> +<span class="special">};</span> +</pre> +<p> + The motivation for this change was to improve compile times. <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> + is an expensive type to instantiate because it defines a host of member functions. + When defining your own expression wrapper, the instance of <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> + sits as a hidden data member function in your wrapper and the members of + <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> go unused. Therefore, + the cost of those member functions is wasted. In contrast, <code class="computeroutput"><a class="link" href="../boost/proto/basic_expr.html" title="Struct template basic_expr">proto::basic_expr<></a></code> + is a very lightweight type with no member functions at all. + </p> +<p> + The vast majority of programs should recompile without any source changes. + However, if somewhere you are assuming that you will be given instances specifically + of <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code>, your code will break. + </p> +<p> + <span class="bold"><strong>New Feature: Sub-domains</strong></span> + </p> +<p> + In Boost 1.44, Proto introduces an important new feature called "sub-domains". + This gives you a way to spcify that one domain is compatible with another + such that expressions in one domain can be freely mixed with expressions + in another. You can define one domain to be the sub-domain of another by + using the third template parameter of <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code>. + </p> +<p> + For instance: + </p> +<pre class="programlisting"><span class="comment">// Not shown: define some expression</span> +<span class="comment">// generators genA and genB</span> + +<span class="keyword">struct</span> <span class="identifier">A</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">genA</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Define a domain B that is the sub-domain</span> +<span class="comment">// of domain A.</span> +<span class="keyword">struct</span> <span class="identifier">B</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">genB</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">A</span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Expressions in domains <code class="computeroutput"><span class="identifier">A</span></code> + and <code class="computeroutput"><span class="identifier">B</span></code> can have different + wrappers (hence, different interfaces), but they can be combined into larger + expressions. Without a sub-domain relationship, this would have been an error. + The domain of the resulting expression in this case would be <code class="computeroutput"><span class="identifier">A</span></code>. + </p> +<p> + The complete description of sub-domains can be found in the reference sections + for <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/deduce_domain.html" title="Struct deduce_domain">proto::deduce_domain</a></code>. + </p> +<p> + <span class="bold"><strong>New Feature: Domain-specific as_expr() and as_child()</strong></span> + </p> +<p> + Proto has always allowed users to customize expressions post-hoc by specifying + a Generator when defining their domain. But it has never allowed users to + control how Proto assembles sub-expressions in the first place. As of Boost + 1.44, users now have this power. + </p> +<p> + Users defining their own domain can now specify how <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> + and <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> work in their domain. They + can do this easily by defining nested class templates named <code class="computeroutput"><span class="identifier">as_expr</span></code> and/or <code class="computeroutput"><span class="identifier">as_child</span></code> + within their domain class. + </p> +<p> + For example: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">my_generator</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">my_generator</span> <span class="special">></span> + <span class="identifier">base_domain</span><span class="special">;</span> + + <span class="comment">// For my_domain, as_child does the same as</span> + <span class="comment">// what as_expr does by default.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">as_child</span> + <span class="special">:</span> <span class="identifier">base_domain</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> + <span class="special">{};</span> +<span class="special">};</span> +</pre> +<p> + In the above example, <code class="computeroutput"><span class="identifier">my_domain</span><span class="special">::</span><span class="identifier">as_child</span><span class="special"><></span></code> simply defers to <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><></span></code>. This has the nice effect of causing + all terminals to be captured by value instead of by reference, and to likewise + store child expressions by value. The result is that expressions in <code class="computeroutput"><span class="identifier">my_domain</span></code> are safe to store in <code class="computeroutput"><span class="keyword">auto</span></code> variables because they will not have + dangling references to intermediate temporary expressions. (Naturally, it + also means that expression construction has extra runtime overhead of copying + that the compiler may or may not be able to optimize away.) + </p> +<h5> +<a name="boost_proto.appendices.release_notes.h1"></a> + <span><a name="boost_proto.appendices.release_notes.boost_1_43"></a></span><a class="link" href="appendices.html#boost_proto.appendices.release_notes.boost_1_43">Boost + 1.43</a> + </h5> +<p> + In Boost 1.43, the recommended usage of <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + changed slightly. The new usage looks like this: + </p> +<pre class="programlisting"><span class="comment">// my_expr is an expression extension of the Expr parameter</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">my_expr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">my_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">my_expr</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">my_expr</span><span class="special">,</span> <span class="identifier">my_domain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// NEW: use the following macro to bring</span> + <span class="comment">// proto::extends::operator= into scope.</span> + <span class="identifier">BOOST_PROTO_EXTENDS_USING_ASSIGN</span><span class="special">(</span><span class="identifier">my_expr</span><span class="special">)</span> +<span class="special">};</span> +</pre> +<p> + The new thing is the use of the <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_USING_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_USING_ASSIGN">BOOST_PROTO_EXTENDS_USING_ASSIGN</a></code>()</code> + macro. To allow assignment operators to build expression trees, <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> overloads the assignment + operator. However, for the <code class="computeroutput"><span class="identifier">my_expr</span></code> + template, the compiler generates a default copy assignment operator that + hides the ones in <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code>. This is often not desired + (although it depends on the syntax you want to allow). + </p> +<p> + Previously, the recommended usage was to do this: + </p> +<pre class="programlisting"><span class="comment">// my_expr is an expression extension of the Expr parameter</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">my_expr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">my_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">my_expr</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">my_expr</span><span class="special">,</span> <span class="identifier">my_domain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// OLD: don't do it like this anymore.</span> + <span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">my_expr</span><span class="special">,</span> <span class="identifier">my_domain</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=;</span> +<span class="special">};</span> +</pre> +<p> + While this works in the majority of cases, it still doesn't suppress the + implicit generation of the default assignment operator. As a result, expressions + of the form <code class="computeroutput"><span class="identifier">a</span> <span class="special">=</span> + <span class="identifier">b</span></code> could either build an expression + template or do a copy assignment depending on whether the types of <code class="computeroutput"><span class="identifier">a</span></code> and <code class="computeroutput"><span class="identifier">b</span></code> + happen to be the same. That can lead to subtle bugs, so the behavior was + changed. + </p> +<p> + The <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_USING_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_USING_ASSIGN">BOOST_PROTO_EXTENDS_USING_ASSIGN</a></code>()</code> + brings into scope the assignment operators defined in <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + as well as suppresses the generation of the copy assignment operator. + </p> +<p> + Also note that the <code class="computeroutput"><a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal<></a></code> class template, which + uses <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code>, has been chaged to use + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_USING_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_USING_ASSIGN">BOOST_PROTO_EXTENDS_USING_ASSIGN</a></code>()</code>. + The implications are highlighted in the sample code below: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">a</span><span class="special">(</span><span class="number">1</span><span class="special">),</span> <span class="identifier">b</span><span class="special">(</span><span class="number">2</span><span class="special">);</span> <span class="comment">// two non-const proto literals</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">c</span><span class="special">(</span><span class="number">3</span><span class="special">);</span> <span class="comment">// a const proto literal</span> + +<span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span> <span class="comment">// No-op. Builds an expression tree and discards it.</span> + <span class="comment">// Same behavior in 1.42 and 1.43.</span> + +<span class="identifier">a</span> <span class="special">=</span> <span class="identifier">c</span><span class="special">;</span> <span class="comment">// CHANGE! In 1.42, this performed copy assignment, causing</span> + <span class="comment">// a's value to change to 3. In 1.43, the behavior is now</span> + <span class="comment">// the same as above: build and discard an expression tree.</span> +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.appendices.history"></a><a class="link" href="appendices.html#boost_proto.appendices.history" title="Appendix B: History">Appendix B: History</a> +</h3></div></div></div> +<div class="variablelist"> +<p class="title"><b></b></p> +<dl> +<dt><span class="term">August ??, 2010</span></dt> +<dd><p> + Boost 1.44: Proto gets sub-domains and per-domain control of <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> to meet the needs + of Phoenix3. + </p></dd> +<dt><span class="term">August 11, 2008</span></dt> +<dd><p> + Proto v4 is merged to Boost trunk with more powerful transform protocol. + </p></dd> +<dt><span class="term">April 7, 2008</span></dt> +<dd><p> + Proto is accepted into Boost. + </p></dd> +<dt><span class="term">March 1, 2008</span></dt> +<dd><p> + Proto's Boost review begins. + </p></dd> +<dt><span class="term">January 11, 2008</span></dt> +<dd><p> + Boost.Proto v3 brings separation of grammars and transforms and a "round" + lambda syntax for defining transforms in-place. + </p></dd> +<dt><span class="term">April 15, 2007</span></dt> +<dd><p> + Boost.Xpressive is ported from Proto compilers to Proto transforms. + Support for old Proto compilers is dropped. + </p></dd> +<dt><span class="term">April 4, 2007</span></dt> +<dd><p> + Preliminary submission of Proto to Boost. + </p></dd> +<dt><span class="term">December 11, 2006</span></dt> +<dd><p> + The idea for transforms that decorate grammar rules is born in a private + email discussion with Joel de Guzman and Hartmut Kaiser. The first + transforms are committed to CVS 5 days later on December 16. + </p></dd> +<dt><span class="term">November 1, 2006</span></dt> +<dd><p> + The idea for <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><></span></code> and the whole grammar facility + is hatched during a discussion with Hartmut Kaiser on the spirit-devel + list. The first version of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><></span></code> is checked into CVS 3 days + later. Message is <a href="http://osdir.com/ml/parsers.spirit.devel/2006-11/msg00003.html" target="_top">here</a>. + </p></dd> +<dt><span class="term">October 28, 2006</span></dt> +<dd><p> + Proto is reborn, this time with a uniform expression types that are + POD. Announcement is <a href="http://lists.boost.org/Archives/boost/2006/10/112453.php" target="_top">here</a>. + </p></dd> +<dt><span class="term">April 20, 2005</span></dt> +<dd><p> + Proto is born as a major refactorization of Boost.Xpressive's meta-programming. + Proto offers expression types, operator overloads and "compilers", + an early formulation of what later became transforms. Announcement + is <a href="http://lists.boost.org/Archives/boost/2005/04/85256.php" target="_top">here</a>. + </p></dd> +</dl> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.appendices.rationale"></a><a class="link" href="appendices.html#boost_proto.appendices.rationale" title="Appendix C: Rationale">Appendix C: Rationale</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.rationale.static_initialization">Static + Initialization</a></span></dt> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.rationale.preprocessor">Why + Not Reuse MPL, Fusion, et cetera?</a></span></dt> +</dl></div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.appendices.rationale.static_initialization"></a><a class="link" href="appendices.html#boost_proto.appendices.rationale.static_initialization" title="Static Initialization">Static + Initialization</a> +</h4></div></div></div> +<p> + Proto expression types are PODs (Plain Old Data), and do not have constructors. + They are brace-initialized, as follows: + </p> +<pre class="programlisting"><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_i</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">};</span> +</pre> +<p> + The reason is so that expression objects like <code class="computeroutput"><span class="identifier">_i</span></code> + above can be <span class="emphasis"><em>statically initialized</em></span>. Why is static + initialization important? The terminals of many embedded domain-specific + languages are likely to be global const objects, like <code class="computeroutput"><span class="identifier">_1</span></code> + and <code class="computeroutput"><span class="identifier">_2</span></code> from the Boost Lambda + Library. Were these object to require run-time initialization, it might + be possible to use these objects before they are initialized. That would + be bad. Statically initialized objects cannot be misused that way. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.appendices.rationale.preprocessor"></a><a class="link" href="appendices.html#boost_proto.appendices.rationale.preprocessor" title="Why Not Reuse MPL, Fusion, et cetera?">Why + Not Reuse MPL, Fusion, et cetera?</a> +</h4></div></div></div> +<p> + Anyone who has peeked at Proto's source code has probably wondered, "Why + all the dirty preprocessor gunk? Couldn't this have been all implemented + cleanly on top of libraries like MPL and Fusion?" The answer is that + Proto could have been implemented this way, and in fact was at one point. + The problem is that template metaprogramming (TMP) makes for longer compile + times. As a foundation upon which other TMP-heavy libraries will be built, + Proto itself should be as lightweight as possible. That is achieved by + prefering preprocessor metaprogramming to template metaprogramming. Expanding + a macro is far more efficient than instantiating a template. In some cases, + the "clean" version takes 10x longer to compile than the "dirty" + version. + </p> +<p> + The "clean and slow" version of Proto can still be found at http://svn.boost.org/svn/boost/branches/proto/v3. + Anyone who is interested can download it and verify that it is, in fact, + unusably slow to compile. Note that this branch's development was abandoned, + and it does not conform exactly with Proto's current interface. + </p> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.appendices.implementation"></a><a class="link" href="appendices.html#boost_proto.appendices.implementation" title="Appendix D: Implementation Notes">Appendix D: Implementation + Notes</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.implementation.sfinae">Quick-n-Dirty + Type Categorization</a></span></dt> +<dt><span class="section"><a href="appendices.html#boost_proto.appendices.implementation.function_arity">Detecting + the Arity of Function Objects</a></span></dt> +</dl></div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.appendices.implementation.sfinae"></a><a class="link" href="appendices.html#boost_proto.appendices.implementation.sfinae" title="Quick-n-Dirty Type Categorization">Quick-n-Dirty + Type Categorization</a> +</h4></div></div></div> +<p> + Much has already been written about dispatching on type traits using SFINAE + (Substitution Failure Is Not An Error) techniques in C++. There is a Boost + library, Boost.Enable_if, to make the technique idiomatic. Proto dispatches + on type traits extensively, but it doesn't use <code class="computeroutput"><span class="identifier">enable_if</span><span class="special"><></span></code> very often. Rather, it dispatches + based on the presence or absence of nested types, often typedefs for void. + </p> +<p> + Consider the implementation of <code class="computeroutput"><span class="identifier">is_expr</span><span class="special"><></span></code>. It could have been written as + something like this: + </p> +<pre class="programlisting"><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">is_expr</span> + <span class="special">:</span> <span class="identifier">is_base_and_derived</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">some_expr_base</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Rather, it is implemented as this: + </p> +<pre class="programlisting"><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">typename</span> <span class="identifier">Void</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">is_expr</span> + <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">false_</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">is_expr</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">proto_is_expr_</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">true_</span> +<span class="special">{};</span> +</pre> +<p> + This relies on the fact that the specialization will be preferred if <code class="computeroutput"><span class="identifier">T</span></code> has a nested <code class="computeroutput"><span class="identifier">proto_is_expr_</span></code> + that is a typedef for <code class="computeroutput"><span class="keyword">void</span></code>. + All Proto expression types have such a nested typedef. + </p> +<p> + Why does Proto do it this way? The reason is because, after running extensive + benchmarks while trying to improve compile times, I have found that this + approach compiles faster. It requires exactly one template instantiation. + The other approach requires at least 2: <code class="computeroutput"><span class="identifier">is_expr</span><span class="special"><></span></code> and <code class="computeroutput"><span class="identifier">is_base_and_derived</span><span class="special"><></span></code>, plus whatever templates <code class="computeroutput"><span class="identifier">is_base_and_derived</span><span class="special"><></span></code> + may instantiate. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.appendices.implementation.function_arity"></a><a class="link" href="appendices.html#boost_proto.appendices.implementation.function_arity" title="Detecting the Arity of Function Objects">Detecting + the Arity of Function Objects</a> +</h4></div></div></div> +<p> + In several places, Proto needs to know whether or not a function object + <code class="computeroutput"><span class="identifier">Fun</span></code> can be called with + certain parameters and take a fallback action if not. This happens in + <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + and in the <code class="computeroutput"><a class="link" href="../boost/proto/call.html" title="Struct template call">proto::call<></a></code> transform. How does + Proto know? It involves some tricky metaprogramming. Here's how. + </p> +<p> + Another way of framing the question is by trying to implement the following + <code class="computeroutput"><span class="identifier">can_be_called</span><span class="special"><></span></code> + Boolean metafunction, which checks to see if a function object <code class="computeroutput"><span class="identifier">Fun</span></code> can be called with parameters of + type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Fun</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">B</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">can_be_called</span><span class="special">;</span> +</pre> +<p> + First, we define the following <code class="computeroutput"><span class="identifier">dont_care</span></code> + struct, which has an implicit conversion from anything. And not just any + implicit conversion; it has a ellipsis conversion, which is the worst possible + conversion for the purposes of overload resolution: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">dont_care</span> +<span class="special">{</span> + <span class="identifier">dont_care</span><span class="special">(...);</span> +<span class="special">};</span> +</pre> +<p> + We also need some private type known only to us with an overloaded comma + operator (!), and some functions that detect the presence of this type + and return types with different sizes, as follows: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">private_type</span> +<span class="special">{</span> + <span class="identifier">private_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="keyword">operator</span><span class="special">,(</span><span class="keyword">int</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span> +<span class="special">};</span> + +<span class="keyword">typedef</span> <span class="keyword">char</span> <span class="identifier">yes_type</span><span class="special">;</span> <span class="comment">// sizeof(yes_type) == 1</span> +<span class="keyword">typedef</span> <span class="keyword">char</span> <span class="special">(&</span><span class="identifier">no_type</span><span class="special">)[</span><span class="number">2</span><span class="special">];</span> <span class="comment">// sizeof(no_type) == 2</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="identifier">no_type</span> <span class="identifier">is_private_type</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&);</span> + +<span class="identifier">yes_type</span> <span class="identifier">is_private_type</span><span class="special">(</span><span class="identifier">private_type</span> <span class="keyword">const</span> <span class="special">&);</span> +</pre> +<p> + Next, we implement a binary function object wrapper with a very strange + conversion operator, whose meaning will become clear later. + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Fun</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">funwrap2</span> <span class="special">:</span> <span class="identifier">Fun</span> +<span class="special">{</span> + <span class="identifier">funwrap2</span><span class="special">();</span> + <span class="keyword">typedef</span> <span class="identifier">private_type</span> <span class="keyword">const</span> <span class="special">&(*</span><span class="identifier">pointer_to_function</span><span class="special">)(</span><span class="identifier">dont_care</span><span class="special">,</span> <span class="identifier">dont_care</span><span class="special">);</span> + <span class="keyword">operator</span> <span class="identifier">pointer_to_function</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + With all of these bits and pieces, we can implement <code class="computeroutput"><span class="identifier">can_be_called</span><span class="special"><></span></code> as follows: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Fun</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">B</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">can_be_called</span> +<span class="special">{</span> + <span class="keyword">static</span> <span class="identifier">funwrap2</span><span class="special"><</span><span class="identifier">Fun</span><span class="special">></span> <span class="special">&</span><span class="identifier">fun</span><span class="special">;</span> + <span class="keyword">static</span> <span class="identifier">A</span> <span class="special">&</span><span class="identifier">a</span><span class="special">;</span> + <span class="keyword">static</span> <span class="identifier">B</span> <span class="special">&</span><span class="identifier">b</span><span class="special">;</span> + + <span class="keyword">static</span> <span class="keyword">bool</span> <span class="keyword">const</span> <span class="identifier">value</span> <span class="special">=</span> <span class="special">(</span> + <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">no_type</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">is_private_type</span><span class="special">(</span> <span class="special">(</span><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</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">mpl</span><span class="special">::</span><span class="identifier">bool_</span><span class="special"><</span><span class="identifier">value</span><span class="special">></span> <span class="identifier">type</span><span class="special">;</span> +<span class="special">};</span> +</pre> +<p> + The idea is to make it so that <code class="computeroutput"><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">)</span></code> will + always compile by adding our own binary function overload, but doing it + in such a way that we can detect whether our overload was selected or not. + And we rig it so that our overload is selected if there is really no better + option. What follows is a description of how <code class="computeroutput"><span class="identifier">can_be_called</span><span class="special"><></span></code> works. + </p> +<p> + We wrap <code class="computeroutput"><span class="identifier">Fun</span></code> in a type that + has an implicit conversion to a pointer to a binary function. An object + <code class="computeroutput"><span class="identifier">fun</span></code> of class type can be + invoked as <code class="computeroutput"><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code> if it has such a conversion operator, + but since it involves a user-defined conversion operator, it is less preferred + than an overloaded <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>, which requires no such conversion. + </p> +<p> + The function pointer can accept any two arguments by virtue of the <code class="computeroutput"><span class="identifier">dont_care</span></code> type. The conversion sequence + for each argument is guaranteed to be the worst possible conversion sequence: + an implicit conversion through an ellipsis, and a user-defined conversion + to <code class="computeroutput"><span class="identifier">dont_care</span></code>. In total, + it means that <code class="computeroutput"><span class="identifier">funwrap2</span><span class="special"><</span><span class="identifier">Fun</span><span class="special">>()(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code> + will always compile, but it will select our overload only if there really + is no better option. + </p> +<p> + If there is a better option --- for example if <code class="computeroutput"><span class="identifier">Fun</span></code> + has an overloaded function call operator such as <code class="computeroutput"><span class="keyword">void</span> + <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">A</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">B</span> <span class="identifier">b</span><span class="special">)</span></code> --- + then <code class="computeroutput"><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code> will resolve to that one instead. The + question now is how to detect which function got picked by overload resolution. + </p> +<p> + Notice how <code class="computeroutput"><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code> appears in <code class="computeroutput"><span class="identifier">can_be_called</span><span class="special"><></span></code>: <code class="computeroutput"><span class="special">(</span><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">),</span> <span class="number">0</span><span class="special">)</span></code>. + Why do we use the comma operator there? The reason is because we are using + this expression as the argument to a function. If the return type of <code class="computeroutput"><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code> is <code class="computeroutput"><span class="keyword">void</span></code>, + it cannot legally be used as an argument to a function. The comma operator + sidesteps the issue. + </p> +<p> + This should also make plain the purpose of the overloaded comma operator + in <code class="computeroutput"><span class="identifier">private_type</span></code>. The return + type of the pointer to function is <code class="computeroutput"><span class="identifier">private_type</span></code>. + If overload resolution selects our overload, then the type of <code class="computeroutput"><span class="special">(</span><span class="identifier">fun</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> + <span class="identifier">b</span><span class="special">),</span> + <span class="number">0</span><span class="special">)</span></code> + is <code class="computeroutput"><span class="identifier">private_type</span></code>. Otherwise, + it is <code class="computeroutput"><span class="keyword">int</span></code>. That fact is used + to dispatch to either overload of <code class="computeroutput"><span class="identifier">is_private_type</span><span class="special">()</span></code>, which encodes its answer in the size + of its return type. + </p> +<p> + That's how it works with binary functions. Now repeat the above process + for functions up to some predefined function arity, and you're done. + </p> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.appendices.acknowledgements"></a><a class="link" href="appendices.html#boost_proto.appendices.acknowledgements" title="Appendix E: Acknowledgements">Appendix E: + Acknowledgements</a> +</h3></div></div></div> +<p> + I'd like to thank Joel de Guzman and Hartmut Kaiser for being willing to + take a chance on using Proto for their work on Spirit-2 and Karma when Proto + was little more than a vision. Their requirements and feedback have been + indespensable. + </p> +<p> + Thanks also to Thomas Heller and again to Hartmut for their feedback and + suggestions during the redesign of Phoenix. That effort yielded several valuable + advanced features such as sub-domains, external transforms, and per-domain + <code class="computeroutput"><span class="identifier">as_child</span></code> customization. + </p> +<p> + Thanks to Daniel James for providing a patch to remove the dependence on + deprecated configuration macros for C++0x features. + </p> +<p> + Thanks to Joel Falcou and Christophe Henry for their enthusiasm, support, + feedback, and humor; and for volunteering to be Proto's co-maintainers. + </p> +<p> + Thanks to Dave Abrahams for an especially detailed review, and for making + a VM with msvc-7.1 available so I could track down portability issues on + that compiler. + </p> +<p> + Many thanks to Daniel Wallin who first implemented the code used to find + the common domain among a set, accounting for super- and sub-domains. Thanks + also to Jeremiah Willcock, John Bytheway and Krishna Achuthan who offered + alternate solutions to this tricky programming problem. + </p> +<p> + Thanks also to the developers of <a href="http://www.codesourcery.com/pooma/download.html" target="_top">PETE</a>. + I found many good ideas there. + </p> +</div> +</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 © 2008 Eric Niebler<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="../Transform.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../boost_random.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/proto/reference.html b/doc/html/proto/reference.html new file mode 100755 index 0000000000..4f19012e26 --- /dev/null +++ b/doc/html/proto/reference.html @@ -0,0 +1,2052 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Reference</title> +<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> +<link rel="up" href="../proto.html" title="Chapter 20. Boost.Proto"> +<link rel="prev" href="users_guide.html" title="Users' Guide"> +<link rel="next" href="../boost/proto/term.html" title="Struct template term"> +</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.html">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="users_guide.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../boost/proto/term.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="proto.reference"></a>Reference</h2></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="reference.html#proto.concepts">Concepts</a></span></dt> +<dt><span class="section"><a href="reference.html#proto.reference.classes">Classes</a></span></dt> +<dt><span class="section"><a href="reference.html#proto.reference.functions">Functions</a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.args_hpp">Header <boost/proto/args.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.core_hpp">Header <boost/proto/core.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.debug_hpp">Header <boost/proto/debug.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.deep_copy_hpp">Header <boost/proto/deep_copy.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.domain_hpp">Header <boost/proto/domain.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.eval_hpp">Header <boost/proto/eval.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.expr_hpp">Header <boost/proto/expr.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.extends_hpp">Header <boost/proto/extends.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional_hpp">Header <boost/proto/functional.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion_hpp">Header <boost/proto/functional/fusion.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion.at_hpp">Header <boost/proto/functional/fusion/at.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion.pop_back_hpp">Header <boost/proto/functional/fusion/pop_back.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion.pop_front_hpp">Header <boost/proto/functional/fusion/pop_front.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion.push_back_hpp">Header <boost/proto/functional/fusion/push_back.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion.push_front_hpp">Header <boost/proto/functional/fusion/push_front.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.fusion.reverse_hpp">Header <boost/proto/functional/fusion/reverse.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.std_hpp">Header <boost/proto/functional/std.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.functional.std.utility_hpp">Header <boost/proto/functional/std/utility.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.fusion_hpp">Header <boost/proto/fusion.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.generate_hpp">Header <boost/proto/generate.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.literal_hpp">Header <boost/proto/literal.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.make_expr_hpp">Header <boost/proto/make_expr.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.matches_hpp">Header <boost/proto/matches.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.operators_hpp">Header <boost/proto/operators.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.proto_hpp">Header <boost/proto/proto.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.proto_fwd_hpp">Header <boost/proto/proto_fwd.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.proto_typeof_hpp">Header <boost/proto/proto_typeof.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.repeat_hpp">Header <boost/proto/repeat.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.tags_hpp">Header <boost/proto/tags.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.traits_hpp">Header <boost/proto/traits.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform_hpp">Header <boost/proto/transform.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.arg_hpp">Header <boost/proto/transform/arg.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.call_hpp">Header <boost/proto/transform/call.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.default_hpp">Header <boost/proto/transform/default.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.fold_hpp">Header <boost/proto/transform/fold.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.fold_tree_hpp">Header <boost/proto/transform/fold_tree.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.impl_hpp">Header <boost/proto/transform/impl.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.integral_c_hpp">Header <boost/proto/transform/integral_c.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.lazy_hpp">Header <boost/proto/transform/lazy.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.make_hpp">Header <boost/proto/transform/make.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.pass_through_hpp">Header <boost/proto/transform/pass_through.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.transform.when_hpp">Header <boost/proto/transform/when.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.context_hpp">Header <boost/proto/context.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.context.callable_hpp">Header <boost/proto/context/callable.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.context.default_hpp">Header <boost/proto/context/default.hpp></a></span></dt> +<dt><span class="section"><a href="reference.html#header.boost.proto.context.null_hpp">Header <boost/proto/context/null.hpp></a></span></dt> +</dl></div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="proto.concepts"></a>Concepts</h3></div></div></div> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"><a class="link" href="../CallableTransform.html" title="Concept CallableTransform">CallableTransform</a></li> +<li class="listitem"><a class="link" href="../Domain.html" title="Concept Domain">Domain</a></li> +<li class="listitem"><a class="link" href="../Expr.html" title="Concept Expr">Expr</a></li> +<li class="listitem"><a class="link" href="../ObjectTransform.html" title="Concept ObjectTransform">ObjectTransform</a></li> +<li class="listitem"><a class="link" href="../PolymorphicFunctionObject.html" title="Concept PolymorphicFunctionObject">PolymorphicFunctionObject</a></li> +<li class="listitem"><a class="link" href="../PrimitiveTransform.html" title="Concept PrimitiveTransform">PrimitiveTransform</a></li> +<li class="listitem"><a class="link" href="../Transform.html" title="Concept Transform">Transform</a></li> +</ul></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="proto.reference.classes"></a>Classes</h3></div></div></div> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_.html" title="Struct _">proto::_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_byref.html" title="Struct _byref">proto::_byref</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_byval.html" title="Struct _byval">proto::_byval</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_child_c.html" title="Struct template _child_c">proto::_child_c</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_data.html" title="Struct _data">proto::_data</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_default.html" title="Struct template _default">proto::_default</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_expr.html" title="Struct _expr">proto::_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_state.html" title="Struct _state">proto::_state</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_value.html" title="Struct _value">proto::_value</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/_void.html" title="Struct _void">proto::_void</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/address_of.html" title="Struct template address_of">proto::address_of</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/arity_of.html" title="Struct template arity_of">proto::arity_of</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/assign.html" title="Struct template assign">proto::assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/basic_default_domain.html" title="Struct basic_default_domain">proto::basic_default_domain</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/basic_default_generator.html" title="Struct basic_default_generator">proto::basic_default_generator</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/basic_expr.html" title="Struct template basic_expr">proto::basic_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/binary_expr.html" title="Struct template binary_expr">proto::binary_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/bitwise_and.html" title="Struct template bitwise_and">proto::bitwise_and</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/bitwise_and_assign.html" title="Struct template bitwise_and_assign">proto::bitwise_and_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/bitwise_or.html" title="Struct template bitwise_or">proto::bitwise_or</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/bitwise_or_assign.html" title="Struct template bitwise_or_assign">proto::bitwise_or_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/bitwise_xor.html" title="Struct template bitwise_xor">proto::bitwise_xor</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/bitwise_xor_assign.html" title="Struct template bitwise_xor_assign">proto::bitwise_xor_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/by_value_generator.html" title="Struct by_value_generator">proto::by_value_generator</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/call.html" title="Struct template call">proto::call</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/callable.html" title="Struct callable">proto::callable</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/char_.html" title="Struct template char_">proto::char_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/comma.html" title="Struct template comma">proto::comma</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/complement.html" title="Struct template complement">proto::complement</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/compose_generators.html" title="Struct template compose_generators">proto::compose_generators</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::context::callable_context</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_eval.html" title="Struct template callable_eval">proto::context::callable_eval</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::context::default_context</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/context/default_eval.html" title="Struct template default_eval">proto::context::default_eval</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/context/null_context.html" title="Struct null_context">proto::context::null_context</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/context/null_eval.html" title="Struct template null_eval">proto::context::null_eval</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/convertible_to.html" title="Struct template convertible_to">proto::convertible_to</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/deduce_domain.html" title="Struct deduce_domain">proto::deduce_domain</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/default_generator.html" title="Struct default_generator">proto::default_generator</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/dereference.html" title="Struct template dereference">proto::dereference</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/divides.html" title="Struct template divides">proto::divides</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/divides_assign.html" title="Struct template divides_assign">proto::divides_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/domain/as_child.html" title="Struct template as_child">proto::domain::as_child</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/domain/as_expr.html" title="Struct template as_expr">proto::domain::as_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/domain_of.html" title="Struct template domain_of">proto::domain_of</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/equal_to.html" title="Struct template equal_to">proto::equal_to</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/exact.html" title="Struct template exact">proto::exact</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/external_transform.html" title="Struct external_transform">proto::external_transform</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/external_transforms.html" title="Struct template external_transforms">proto::external_transforms</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/fold.html" title="Struct template fold">proto::fold</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/fold_tree.html" title="Struct template fold_tree">proto::fold_tree</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/function.html" title="Struct template function">proto::function</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/as_child.html" title="Struct template as_child">proto::functional::as_child</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/as_expr.html" title="Struct template as_expr">proto::functional::as_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/at.html" title="Struct at">proto::functional::at</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/child.html" title="Struct template child">proto::functional::child</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/child_c.html" title="Struct template child_c">proto::functional::child_c</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/deep_copy.html" title="Struct deep_copy">proto::functional::deep_copy</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/display_expr.html" title="Struct display_expr">proto::functional::display_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/eval.html" title="Struct eval">proto::functional::eval</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/first.html" title="Struct first">proto::functional::first</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/flatten.html" title="Struct flatten">proto::functional::flatten</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/left.html" title="Struct left">proto::functional::left</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/make_pair.html" title="Struct make_pair">proto::functional::make_pair</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/pop_back.html" title="Struct pop_back">proto::functional::pop_back</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/pop_front.html" title="Struct pop_front">proto::functional::pop_front</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/push_back.html" title="Struct push_back">proto::functional::push_back</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/push_front.html" title="Struct push_front">proto::functional::push_front</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/reverse.html" title="Struct reverse">proto::functional::reverse</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/right.html" title="Struct right">proto::functional::right</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/second.html" title="Struct second">proto::functional::second</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/unpack_expr.html" title="Struct template unpack_expr">proto::functional::unpack_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/functional/value.html" title="Struct value">proto::functional::value</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/generator.html" title="Struct template generator">proto::generator</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/greater.html" title="Struct template greater">proto::greater</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/greater_equal.html" title="Struct template greater_equal">proto::greater_equal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/if_.html" title="Struct template if_">proto::if_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/if_else_.html" title="Struct template if_else_">proto::if_else_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/int_.html" title="Struct template int_">proto::int_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/integral_c.html" title="Struct template integral_c">proto::integral_c</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_aggregate.html" title="Struct template is_aggregate">proto::is_aggregate</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_callable.html" title="Struct template is_callable">proto::is_callable</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_domain.html" title="Struct template is_domain">proto::is_domain</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_expr.html" title="Struct template is_expr">proto::is_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_extension.html" title="Struct template is_extension">proto::is_extension</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_proto_expr.html" title="Struct is_proto_expr">proto::is_proto_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/is_transform.html" title="Struct template is_transform">proto::is_transform</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/lazy.html" title="Struct template lazy">proto::lazy</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/less.html" title="Struct template less">proto::less</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/less_equal.html" title="Struct template less_equal">proto::less_equal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/listN.html" title="Struct template listN">proto::list1<>, proto::list2<>, ...</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/logical_and.html" title="Struct template logical_and">proto::logical_and</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/logical_not.html" title="Struct template logical_not">proto::logical_not</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/logical_or.html" title="Struct template logical_or">proto::logical_or</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/long_.html" title="Struct template long_">proto::long_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/make.html" title="Struct template make">proto::make</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/mem_ptr.html" title="Struct template mem_ptr">proto::mem_ptr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/minus.html" title="Struct template minus">proto::minus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/minus_assign.html" title="Struct template minus_assign">proto::minus_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/modulus.html" title="Struct template modulus">proto::modulus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/modulus_assign.html" title="Struct template modulus_assign">proto::modulus_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/multiplies.html" title="Struct template multiplies">proto::multiplies</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/multiplies_assign.html" title="Struct template multiplies_assign">proto::multiplies_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/nary_expr.html" title="Struct template nary_expr">proto::nary_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/negate.html" title="Struct template negate">proto::negate</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/noinvoke.html" title="Struct template noinvoke">proto::noinvoke</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/not_.html" title="Struct template not_">proto::not_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/not_equal_to.html" title="Struct template not_equal_to">proto::not_equal_to</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/nullary_expr.html" title="Struct template nullary_expr">proto::nullary_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/otherwise.html" title="Struct template otherwise">proto::otherwise</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/pass_through.html" title="Struct template pass_through">proto::pass_through</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/plus.html" title="Struct template plus">proto::plus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/plus_assign.html" title="Struct template plus_assign">proto::plus_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/pod_generator.html" title="Struct template pod_generator">proto::pod_generator</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/post_dec.html" title="Struct template post_dec">proto::post_dec</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/post_inc.html" title="Struct template post_inc">proto::post_inc</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/pre_dec.html" title="Struct template pre_dec">proto::pre_dec</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/pre_inc.html" title="Struct template pre_inc">proto::pre_inc</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/protect.html" title="Struct template protect">proto::protect</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/as_child.html" title="Struct template as_child">proto::result_of::as_child</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/as_expr.html" title="Struct template as_expr">proto::result_of::as_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">proto::result_of::child</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">proto::result_of::child_c</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/deep_copy.html" title="Struct template deep_copy">proto::result_of::deep_copy</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/eval.html" title="Struct template eval">proto::result_of::eval</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/flatten.html" title="Struct template flatten">proto::result_of::flatten</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/left.html" title="Struct template left">proto::result_of::left</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/make_expr.html" title="Struct template make_expr">proto::result_of::make_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/right.html" title="Struct template right">proto::result_of::right</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/unpack_expr.html" title="Struct template unpack_expr">proto::result_of::unpack_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/value.html" title="Struct template value">proto::result_of::value</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/reverse_fold.html" title="Struct template reverse_fold">proto::reverse_fold</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/reverse_fold_tree.html" title="Struct template reverse_fold_tree">proto::reverse_fold_tree</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/shift_left.html" title="Struct template shift_left">proto::shift_left</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/shift_left_assign.html" title="Struct template shift_left_assign">proto::shift_left_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/shift_right.html" title="Struct template shift_right">proto::shift_right</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/shift_right_assign.html" title="Struct template shift_right_assign">proto::shift_right_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/size_t.html" title="Struct template size_t">proto::size_t</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/subscript.html" title="Struct template subscript">proto::subscript</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/address_of.html" title="Struct address_of">proto::tag::address_of</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/assign.html" title="Struct assign">proto::tag::assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/bitwise_and.html" title="Struct bitwise_and">proto::tag::bitwise_and</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/bitwise_and_assign.html" title="Struct bitwise_and_assign">proto::tag::bitwise_and_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/bitwise_or.html" title="Struct bitwise_or">proto::tag::bitwise_or</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/bitwise_or_assign.html" title="Struct bitwise_or_assign">proto::tag::bitwise_or_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/bitwise_xor.html" title="Struct bitwise_xor">proto::tag::bitwise_xor</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/bitwise_xor_assign.html" title="Struct bitwise_xor_assign">proto::tag::bitwise_xor_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/comma.html" title="Struct comma">proto::tag::comma</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/complement.html" title="Struct complement">proto::tag::complement</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/dereference.html" title="Struct dereference">proto::tag::dereference</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/divides.html" title="Struct divides">proto::tag::divides</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/divides_assign.html" title="Struct divides_assign">proto::tag::divides_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/equal_to.html" title="Struct equal_to">proto::tag::equal_to</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/function.html" title="Struct function">proto::tag::function</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/greater.html" title="Struct greater">proto::tag::greater</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/greater_equal.html" title="Struct greater_equal">proto::tag::greater_equal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/if_else_.html" title="Struct if_else_">proto::tag::if_else_</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/less.html" title="Struct less">proto::tag::less</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/less_equal.html" title="Struct less_equal">proto::tag::less_equal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/logical_and.html" title="Struct logical_and">proto::tag::logical_and</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/logical_not.html" title="Struct logical_not">proto::tag::logical_not</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/logical_or.html" title="Struct logical_or">proto::tag::logical_or</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/mem_ptr.html" title="Struct mem_ptr">proto::tag::mem_ptr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/minus.html" title="Struct minus">proto::tag::minus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/minus_assign.html" title="Struct minus_assign">proto::tag::minus_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/modulus.html" title="Struct modulus">proto::tag::modulus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/modulus_assign.html" title="Struct modulus_assign">proto::tag::modulus_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/multiplies.html" title="Struct multiplies">proto::tag::multiplies</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/multiplies_assign.html" title="Struct multiplies_assign">proto::tag::multiplies_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/negate.html" title="Struct negate">proto::tag::negate</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/not_equal_to.html" title="Struct not_equal_to">proto::tag::not_equal_to</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/plus.html" title="Struct plus">proto::tag::plus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/plus_assign.html" title="Struct plus_assign">proto::tag::plus_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/post_dec.html" title="Struct post_dec">proto::tag::post_dec</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/post_inc.html" title="Struct post_inc">proto::tag::post_inc</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/pre_dec.html" title="Struct pre_dec">proto::tag::pre_dec</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/pre_inc.html" title="Struct pre_inc">proto::tag::pre_inc</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/shift_left.html" title="Struct shift_left">proto::tag::shift_left</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/shift_left_assign.html" title="Struct shift_left_assign">proto::tag::shift_left_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/shift_right.html" title="Struct shift_right">proto::tag::shift_right</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/shift_right_assign.html" title="Struct shift_right_assign">proto::tag::shift_right_assign</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/subscript.html" title="Struct subscript">proto::tag::subscript</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/terminal.html" title="Struct terminal">proto::tag::terminal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag/unary_plus.html" title="Struct unary_plus">proto::tag::unary_plus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/tag_of.html" title="Struct template tag_of">proto::tag_of</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/term.html" title="Struct template term">proto::term</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/transform.html" title="Struct template transform">proto::transform</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/transform_impl.html" title="Struct template transform_impl">proto::transform_impl</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/unary_expr.html" title="Struct template unary_expr">proto::unary_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/unary_plus.html" title="Struct template unary_plus">proto::unary_plus</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/use_basic_expr.html" title="Struct template use_basic_expr">proto::use_basic_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/unexpr.html" title="Struct template unexpr">proto::unexpr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/vararg.html" title="Struct template vararg">proto::vararg</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/wants_basic_expr.html" title="Struct template wants_basic_expr">proto::wants_basic_expr</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when</a></code> + </code></li> +</ul></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="proto.reference.functions"></a>Functions</h3></div></div></div> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/assert_matches.html" title="Function template assert_matches">proto::assert_matches()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/assert_matches_not.html" title="Function template assert_matches_not">proto::assert_matches_not()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/child_id1527766.html" title="Function child">proto::child()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/child_c_id1528008.html" title="Function child_c">proto::child_c()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/deep_copy_id1493807.html" title="Function template deep_copy">proto::deep_copy()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/display_expr_id1492920.html" title="Function display_expr">proto::display_expr()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/flatten_id1500995.html" title="Function flatten">proto::flatten()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="reference.html#boost.proto.if_else">proto::if_else()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/left_id1528275.html" title="Function left">proto::left()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/lit.html" title="Function lit">proto::lit()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/right_id1528399.html" title="Function right">proto::right()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/unpack_expr_id1504094.html" title="Function unpack_expr">proto::unpack_expr()</a></code> + </code></li> +<li class="listitem"><code class="computeroutput"> + <code class="computeroutput"><a class="link" href="../boost/proto/value_id1528169.html" title="Function value">proto::value()</a></code> + </code></li> +</ul></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.args_hpp"></a>Header <<a href="../../../boost/proto/args.hpp" target="_top">boost/proto/args.hpp</a>></h3></div></div></div> +<p> + Contains definitions of the <code class="computeroutput"> + <a class="link" href="../boost/proto/term.html" title="Struct template term">proto::term<></a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/listN.html" title="Struct template listN">proto::list1<></a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/listN.html" title="Struct template listN">proto::list2<></a></code>, etc. + class templates. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/term.html" title="Struct template term">term</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span><span class="special">...</span> Arg<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/listN.html" title="Struct template listN">listN</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.core_hpp"></a>Header <<a href="../../../boost/proto/core.hpp" target="_top">boost/proto/core.hpp</a>></h3></div></div></div> +<p>Includes all of Proto, except the contexts, transforms, debug utilities and Boost.Typeof registrations.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.debug_hpp"></a>Header <<a href="../../../boost/proto/debug.hpp" target="_top">boost/proto/debug.hpp</a>></h3></div></div></div> +<p>Utilities for debugging Proto expression trees </p> +<pre class="synopsis"> + +<a class="link" href="../BOOST_PROTO_ASSERT_MATCHES.html" title="Macro BOOST_PROTO_ASSERT_MATCHES">BOOST_PROTO_ASSERT_MATCHES</a>(expr, Grammar) +<a class="link" href="../BOOST_PROTO_ASSERT_MATCHES_NOT.html" title="Macro BOOST_PROTO_ASSERT_MATCHES_NOT">BOOST_PROTO_ASSERT_MATCHES_NOT</a>(expr, Grammar)</pre> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">void</span> <a class="link" href="../boost/proto/display_expr_id1492920.html" title="Function display_expr"><span class="identifier">display_expr</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">void</span> <a class="link" href="../boost/proto/display_expr_id1492920.html" title="Function display_expr"><span class="identifier">display_expr</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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> Grammar<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">void</span> <a class="link" href="../boost/proto/assert_matches.html" title="Function template assert_matches"><span class="identifier">assert_matches</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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> Grammar<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">void</span> <a class="link" href="../boost/proto/assert_matches_not.html" title="Function template assert_matches_not"><span class="identifier">assert_matches_not</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/display_expr.html" title="Struct display_expr">display_expr</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.deep_copy_hpp"></a>Header <<a href="../../../boost/proto/deep_copy.hpp" target="_top">boost/proto/deep_copy.hpp</a>></h3></div></div></div> +<p>Replace all nodes stored by reference by nodes stored by value.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/deep_copy.html" title="Struct template deep_copy">proto::result_of::deep_copy</a><span class="special"><</span><span class="identifier">Expr</span><span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/deep_copy_id1493807.html" title="Function template deep_copy"><span class="identifier">deep_copy</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/deep_copy.html" title="Struct template deep_copy">deep_copy</a><span class="special">;</span> + <span class="special">}</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/deep_copy.html" title="Struct deep_copy">deep_copy</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.domain_hpp"></a>Header <<a href="../../../boost/proto/domain.hpp" target="_top">boost/proto/domain.hpp</a>></h3></div></div></div> +<p> + Contains definition of the <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a> + </code> class template and helpers for defining domains with a generator for customizing expression + construction and a grammar for controlling operator overloading. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Generator <span class="special">=</span> <a class="link" href="../boost/proto/default_generator.html" title="Struct default_generator">proto::default_generator</a><span class="special">,</span> + <span class="keyword">typename</span> Grammar <span class="special">=</span> <a class="link" href="../boost/proto/_.html" title="Struct _">proto::_</a><span class="special">,</span> <span class="keyword">typename</span> Super <span class="special">=</span> <em class="replaceable"><code><span class="identifier">unspecified</span></code></em><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/domain.html" title="Struct template domain">domain</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">default_domain</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/basic_default_domain.html" title="Struct basic_default_domain">basic_default_domain</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/deduce_domain.html" title="Struct deduce_domain">deduce_domain</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_domain.html" title="Struct template is_domain">is_domain</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/domain_of.html" title="Struct template domain_of">domain_of</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.eval_hpp"></a>Header <<a href="../../../boost/proto/eval.hpp" target="_top">boost/proto/eval.hpp</a>></h3></div></div></div> +<p> + Contains the + <code class="computeroutput"> + <a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a> + </code> expression evaluator. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Context<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/eval.html" title="Struct template eval">proto::result_of::eval</a><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval"><span class="identifier">eval</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">Context</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Context<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/eval.html" title="Struct template eval">proto::result_of::eval</a><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval"><span class="identifier">eval</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/eval.html" title="Struct eval">eval</a><span class="special">;</span> + <span class="special">}</span> + <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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Context<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/eval.html" title="Struct template eval">eval</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.expr_hpp"></a>Header <<a href="../../../boost/proto/expr.hpp" target="_top">boost/proto/expr.hpp</a>></h3></div></div></div> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> Args<span class="special">,</span> <span class="keyword">long</span> Arity <span class="special">=</span> <span class="identifier">Args</span><span class="special">::</span><span class="identifier">arity</span><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/basic_expr.html" title="Struct template basic_expr">basic_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> Args<span class="special">,</span> <span class="keyword">long</span> Arity <span class="special">=</span> <span class="identifier">Args</span><span class="special">::</span><span class="identifier">arity</span><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/expr.html" title="Struct template expr">expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/unexpr.html" title="Struct template unexpr">unexpr</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.extends_hpp"></a>Header <<a href="../../../boost/proto/extends.hpp" target="_top">boost/proto/extends.hpp</a>></h3></div></div></div> +<p>Macros and a base class for defining end-user expression types </p> +<pre class="synopsis"> + +<a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a>(Expr, Derived, Domain) +<a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a>(Expr, Derived, Domain) +<a class="link" href="../BOOST_PROTO_EXTENDS_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_ASSIGN">BOOST_PROTO_EXTENDS_ASSIGN</a>() +<a class="link" href="../BOOST_PROTO_EXTENDS_FUNCTION.html" title="Macro BOOST_PROTO_EXTENDS_FUNCTION">BOOST_PROTO_EXTENDS_FUNCTION</a>() +<a class="link" href="../BOOST_PROTO_EXTENDS_SUBSCRIPT.html" title="Macro BOOST_PROTO_EXTENDS_SUBSCRIPT">BOOST_PROTO_EXTENDS_SUBSCRIPT</a>() +<a class="link" href="../BOOST_PROTO_EXTENDS_USING_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_USING_ASSIGN">BOOST_PROTO_EXTENDS_USING_ASSIGN</a>(Derived) +<a class="link" href="../BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT.html" title="Macro BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT">BOOST_PROTO_EXTENDS_USING_ASSIGN_NON_DEPENDENT</a>(Derived)</pre> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_proto_expr.html" title="Struct is_proto_expr">is_proto_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Derived<span class="special">,</span> + <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/extends.html" title="Struct template extends">extends</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional_hpp"></a>Header <<a href="../../../boost/proto/functional.hpp" target="_top">boost/proto/functional.hpp</a>></h3></div></div></div> +<p>Includes all the functional extensions of Proto.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion.hpp" target="_top">boost/proto/functional/fusion.hpp</a>></h3></div></div></div> +<p>Includes all the functional extensions to Proto for the Boost.Fusion library.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion.at_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion/at.hpp" target="_top">boost/proto/functional/fusion/at.hpp</a>></h3></div></div></div> +<p>Includes Proto callable <code class="computeroutput"><a class="link" href="../boost/proto/functional/at.html" title="Struct at">boost::proto::functional::at</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/at.html" title="Struct at">at</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion.pop_back_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion/pop_back.hpp" target="_top">boost/proto/functional/fusion/pop_back.hpp</a>></h3></div></div></div> +<p>Includes Proto callable <code class="computeroutput"><a class="link" href="../boost/proto/functional/pop_back.html" title="Struct pop_back">boost::proto::functional::pop_back</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/pop_back.html" title="Struct pop_back">pop_back</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion.pop_front_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion/pop_front.hpp" target="_top">boost/proto/functional/fusion/pop_front.hpp</a>></h3></div></div></div> +<p>Includes Proto callable <code class="computeroutput"><a class="link" href="../boost/proto/functional/pop_front.html" title="Struct pop_front">boost::proto::functional::pop_front</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/pop_front.html" title="Struct pop_front">pop_front</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion.push_back_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion/push_back.hpp" target="_top">boost/proto/functional/fusion/push_back.hpp</a>></h3></div></div></div> +<p>Includes Proto callable <code class="computeroutput"><a class="link" href="../boost/proto/functional/push_back.html" title="Struct push_back">boost::proto::functional::push_back</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/push_back.html" title="Struct push_back">push_back</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion.push_front_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion/push_front.hpp" target="_top">boost/proto/functional/fusion/push_front.hpp</a>></h3></div></div></div> +<p>Includes Proto callable <code class="computeroutput"><a class="link" href="../boost/proto/functional/push_front.html" title="Struct push_front">boost::proto::functional::push_front</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/push_front.html" title="Struct push_front">push_front</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.fusion.reverse_hpp"></a>Header <<a href="../../../boost/proto/functional/fusion/reverse.hpp" target="_top">boost/proto/functional/fusion/reverse.hpp</a>></h3></div></div></div> +<p>Includes Proto callable <code class="computeroutput"><a class="link" href="../boost/proto/functional/reverse.html" title="Struct reverse">boost::proto::functional::reverse</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/reverse.html" title="Struct reverse">reverse</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.std_hpp"></a>Header <<a href="../../../boost/proto/functional/std.hpp" target="_top">boost/proto/functional/std.hpp</a>></h3></div></div></div> +<p>Includes all the functional extensions to Proto for the standard library.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.functional.std.utility_hpp"></a>Header <<a href="../../../boost/proto/functional/std/utility.hpp" target="_top">boost/proto/functional/std/utility.hpp</a>></h3></div></div></div> +<p>Defines Proto callables <code class="computeroutput"><a class="link" href="../boost/proto/functional/make_pair.html" title="Struct make_pair">boost::proto::functional::make_pair</a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/functional/first.html" title="Struct first">boost::proto::functional::first</a></code> and + <code class="computeroutput"><a class="link" href="../boost/proto/functional/second.html" title="Struct second">boost::proto::functional::second</a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/make_pair.html" title="Struct make_pair">make_pair</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/first.html" title="Struct first">first</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/second.html" title="Struct second">second</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.fusion_hpp"></a>Header <<a href="../../../boost/proto/fusion.hpp" target="_top">boost/proto/fusion.hpp</a>></h3></div></div></div> +<p>Make any Proto expression a valid Fusion sequence </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/flatten.html" title="Struct template flatten">proto::result_of::flatten</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> <a class="link" href="../boost/proto/flatten_id1500995.html" title="Function flatten"><span class="identifier">flatten</span></a><span class="special">(</span><span class="identifier">Expr</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/flatten.html" title="Struct template flatten">proto::result_of::flatten</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> + <a class="link" href="../boost/proto/flatten_id1500995.html" title="Function flatten"><span class="identifier">flatten</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/flatten.html" title="Struct flatten">flatten</a><span class="special">;</span> + <span class="special">}</span> + <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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/flatten.html" title="Struct template flatten">flatten</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.generate_hpp"></a>Header <<a href="../../../boost/proto/generate.hpp" target="_top">boost/proto/generate.hpp</a>></h3></div></div></div> +<p>Contains definition of + <code class="computeroutput"><a class="link" href="../boost/proto/default_generator.html" title="Struct default_generator">proto::default_generator</a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/generator.html" title="Struct template generator">proto::generator</a><></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/pod_generator.html" title="Struct template pod_generator">proto::pod_generator</a><></code> + and other utilities that users can use to post-process new expression objects that + Proto creates.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/default_generator.html" title="Struct default_generator">default_generator</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/basic_default_generator.html" title="Struct basic_default_generator">basic_default_generator</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="special">></span> <span class="keyword">class</span> Extends<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/generator.html" title="Struct template generator">generator</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="special">></span> <span class="keyword">class</span> Extends<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/pod_generator.html" title="Struct template pod_generator">pod_generator</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/by_value_generator.html" title="Struct by_value_generator">by_value_generator</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> First<span class="special">,</span> <span class="keyword">typename</span> Second<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/compose_generators.html" title="Struct template compose_generators">compose_generators</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Generator<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/use_basic_expr.html" title="Struct template use_basic_expr">use_basic_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Generator<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/wants_basic_expr.html" title="Struct template wants_basic_expr">wants_basic_expr</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.literal_hpp"></a>Header <<a href="../../../boost/proto/literal.hpp" target="_top">boost/proto/literal.hpp</a>></h3></div></div></div> +<p> + The + <code class="computeroutput"><a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal<></a></code> + terminal wrapper, and the + <code class="computeroutput"><a class="link" href="../boost/proto/lit.html" title="Function lit">proto::lit()</a></code> + function for creating + <code class="computeroutput"><a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal<></a></code> + wrappers. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/literal.html" title="Struct template literal">literal</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal</a><span class="special"><</span> <span class="identifier">T</span> <span class="special">&</span> <span class="special">></span> <span class="keyword">const</span> <a class="link" href="../boost/proto/lit.html" title="Function lit"><span class="identifier">lit</span></a><span class="special">(</span><span class="identifier">T</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> T<span class="special">></span> <a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal</a><span class="special"><</span> <span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="special">></span> <span class="keyword">const</span> <a class="link" href="../boost/proto/lit.html" title="Function lit"><span class="identifier">lit</span></a><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.make_expr_hpp"></a>Header <<a href="../../../boost/proto/make_expr.hpp" target="_top">boost/proto/make_expr.hpp</a>></h3></div></div></div> +<p> + Definition of the <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a> + </code> and <code class="computeroutput"><a class="link" href="../boost/proto/unpack_expr_id1504094.html" title="Function unpack_expr">proto::unpack_expr()</a> + </code> utilities for building Proto expression nodes from child nodes or from a Fusion sequence of child + nodes, respectively. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/make_expr.html" title="Struct template make_expr">proto::result_of::make_expr</a><span class="special"><</span><span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">A</span> <span class="keyword">const</span><span class="special">...</span><span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> + <a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr"><span class="identifier">make_expr</span></a><span class="special">(</span><span class="identifier">A</span> <span class="keyword">const</span> <span class="special">&</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> Tag<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/make_expr.html" title="Struct template make_expr">proto::result_of::make_expr</a><span class="special"><</span><span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">Domain</span><span class="special">,</span> <span class="identifier">A</span> <span class="keyword">const</span><span class="special">...</span><span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> + <a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr"><span class="identifier">make_expr</span></a><span class="special">(</span><span class="identifier">A</span> <span class="keyword">const</span> <span class="special">&</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> Tag<span class="special">,</span> <span class="keyword">typename</span> Sequence<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/unpack_expr.html" title="Struct template unpack_expr">proto::result_of::unpack_expr</a><span class="special"><</span><span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">Sequence</span> <span class="keyword">const</span><span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> + <a class="link" href="../boost/proto/unpack_expr_id1504094.html" title="Function unpack_expr"><span class="identifier">unpack_expr</span></a><span class="special">(</span><span class="identifier">Sequence</span> <span class="keyword">const</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> Tag<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span> Sequence<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/unpack_expr.html" title="Struct template unpack_expr">proto::result_of::unpack_expr</a><span class="special"><</span><span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">Domain</span><span class="special">,</span> <span class="identifier">Sequence</span> <span class="keyword">const</span><span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> + <a class="link" href="../boost/proto/unpack_expr_id1504094.html" title="Function unpack_expr"><span class="identifier">unpack_expr</span></a><span class="special">(</span><span class="identifier">Sequence</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/deduce_domain.html" title="Struct deduce_domain">proto::deduce_domain</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">make_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/deduce_domain.html" title="Struct deduce_domain">proto::deduce_domain</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/unpack_expr.html" title="Struct template unpack_expr">unpack_expr</a><span class="special">;</span> + <span class="special">}</span> + <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> Tag<span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/make_expr.html" title="Struct template make_expr">make_expr</a><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/make_expr_Tag__Domain___id1503351.html" title="Struct template make_expr<Tag, Domain, A...>">make_expr</a><span class="special"><</span><span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">Domain</span><span class="special">,</span> <span class="identifier">A</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> Tag<span class="special">,</span> <span class="keyword">typename</span> Sequence<span class="special">,</span> <span class="keyword">typename</span> Void <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/unpack_expr.html" title="Struct template unpack_expr">unpack_expr</a><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span> Sequence<span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/unpack_expr_Tag__Domain_id1503713.html" title="Struct template unpack_expr<Tag, Domain, Sequence>">unpack_expr</a><span class="special"><</span><span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">Domain</span><span class="special">,</span> <span class="identifier">Sequence</span><span class="special">></span><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.matches_hpp"></a>Header <<a href="../../../boost/proto/matches.hpp" target="_top">boost/proto/matches.hpp</a>></h3></div></div></div> +<p> + Contains definition of the + <code class="computeroutput"> + <a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a> + </code> + metafunction for determining if a given expression matches a given pattern. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_.html" title="Struct _">_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/not_.html" title="Struct template not_">not_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> If<span class="special">,</span> <span class="keyword">typename</span> Then <span class="special">=</span> <a class="link" href="../boost/proto/_.html" title="Struct _">proto::_</a><span class="special">,</span> + <span class="keyword">typename</span> Else <span class="special">=</span> <a class="link" href="../boost/proto/not_.html" title="Struct template not_">proto::not_</a><span class="special"><</span><a class="link" href="../boost/proto/_.html" title="Struct _">proto::_</a><span class="special">></span> <span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/if_.html" title="Struct template if_">if_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span><span class="special">...</span> G<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/or_.html" title="Struct template or_">or_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span><span class="special">...</span> G<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/and_.html" title="Struct template and_">and_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Cases<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Transform.html" title="Concept Transform">Transform</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">switch_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/exact.html" title="Struct template exact">exact</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/convertible_to.html" title="Struct template convertible_to">convertible_to</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/vararg.html" title="Struct template vararg">vararg</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Grammar<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/matches.html" title="Struct template matches">matches</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.operators_hpp"></a>Header <<a href="../../../boost/proto/operators.hpp" target="_top">boost/proto/operators.hpp</a>></h3></div></div></div> +<p>Contains all the overloaded operators that make it possible to build Proto expression trees. </p> +<pre class="synopsis"> + +<a class="link" href="../BOOST_PROTO_DEFINE_OPERATORS.html" title="Macro BOOST_PROTO_DEFINE_OPERATORS">BOOST_PROTO_DEFINE_OPERATORS</a>(Trait, Domain)</pre> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_extension.html" title="Struct template is_extension">is_extension</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+_id1507501"></a><span class="keyword">operator</span><span class="special">+</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+_id1507529"></a><span class="keyword">operator</span><span class="special">+</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1507558"></a><span class="keyword">operator</span><span class="special">-</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1507586"></a><span class="keyword">operator</span><span class="special">-</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1507615"></a><span class="keyword">operator</span><span class="special">*</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1507644"></a><span class="keyword">operator</span><span class="special">*</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator~_id1507672"></a><span class="keyword">operator</span><span class="special">~</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator~_id1507701"></a><span class="keyword">operator</span><span class="special">~</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&_id1507729"></a><span class="keyword">operator</span><span class="special">&</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&_id1507758"></a><span class="keyword">operator</span><span class="special">&</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator!_id1507786"></a><span class="keyword">operator</span><span class="special">!</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator!_id1507815"></a><span class="keyword">operator</span><span class="special">!</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator++_id1507843"></a><span class="keyword">operator</span><span class="special">++</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator++_id1507872"></a><span class="keyword">operator</span><span class="special">++</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator--_id1507900"></a><span class="keyword">operator</span><span class="special">--</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator--_id1507929"></a><span class="keyword">operator</span><span class="special">--</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator++_id1507957"></a><span class="keyword">operator</span><span class="special">++</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">,</span> <span class="keyword">int</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator++_id1507996"></a><span class="keyword">operator</span><span class="special">++</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">,</span> <span class="keyword">int</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator--_id1508034"></a><span class="keyword">operator</span><span class="special">--</span><span class="special">(</span><span class="identifier">Arg</span> <span class="special">&</span> arg<span class="special">,</span> <span class="keyword">int</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Arg<span class="special">></span> <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator--_id1508072"></a><span class="keyword">operator</span><span class="special">--</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> arg<span class="special">,</span> <span class="keyword">int</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508110"></a><span class="keyword">operator</span><span class="special"><<</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508153"></a><span class="keyword">operator</span><span class="special"><<</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508195"></a><span class="keyword">operator</span><span class="special"><<</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508238"></a><span class="keyword">operator</span><span class="special"><<</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508281"></a><span class="keyword">operator</span><span class="special">>></span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508323"></a><span class="keyword">operator</span><span class="special">>></span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508366"></a><span class="keyword">operator</span><span class="special">>></span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508409"></a><span class="keyword">operator</span><span class="special">>></span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508451"></a><span class="keyword">operator</span><span class="special">*</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508494"></a><span class="keyword">operator</span><span class="special">*</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508537"></a><span class="keyword">operator</span><span class="special">*</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1508579"></a><span class="keyword">operator</span><span class="special">*</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/_id1508622"></a><span class="keyword">operator</span><span class="special">/</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/_id1508665"></a><span class="keyword">operator</span><span class="special">/</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/_id1508707"></a><span class="keyword">operator</span><span class="special">/</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/_id1508750"></a><span class="keyword">operator</span><span class="special">/</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%_id1508793"></a><span class="keyword">operator</span><span class="special">%</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%_id1508835"></a><span class="keyword">operator</span><span class="special">%</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%_id1508878"></a><span class="keyword">operator</span><span class="special">%</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%_id1508921"></a><span class="keyword">operator</span><span class="special">%</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+_id1508963"></a><span class="keyword">operator</span><span class="special">+</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+_id1509006"></a><span class="keyword">operator</span><span class="special">+</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+_id1509049"></a><span class="keyword">operator</span><span class="special">+</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+_id1509091"></a><span class="keyword">operator</span><span class="special">+</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1509134"></a><span class="keyword">operator</span><span class="special">-</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1509177"></a><span class="keyword">operator</span><span class="special">-</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1509219"></a><span class="keyword">operator</span><span class="special">-</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1509262"></a><span class="keyword">operator</span><span class="special">-</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509305"></a><span class="keyword">operator</span><span class="special"><</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509347"></a><span class="keyword">operator</span><span class="special"><</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509390"></a><span class="keyword">operator</span><span class="special"><</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509433"></a><span class="keyword">operator</span><span class="special"><</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509475"></a><span class="keyword">operator</span><span class="special">></span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509518"></a><span class="keyword">operator</span><span class="special">></span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509561"></a><span class="keyword">operator</span><span class="special">></span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1509603"></a><span class="keyword">operator</span><span class="special">></span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509646"></a><span class="keyword">operator</span><span class="special"><=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509689"></a><span class="keyword">operator</span><span class="special"><=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509731"></a><span class="keyword">operator</span><span class="special"><=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509774"></a><span class="keyword">operator</span><span class="special"><=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509817"></a><span class="keyword">operator</span><span class="special">>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509859"></a><span class="keyword">operator</span><span class="special">>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509902"></a><span class="keyword">operator</span><span class="special">>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1509945"></a><span class="keyword">operator</span><span class="special">>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator==_id1509987"></a><span class="keyword">operator</span><span class="special">==</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator==_id1510030"></a><span class="keyword">operator</span><span class="special">==</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator==_id1510073"></a><span class="keyword">operator</span><span class="special">==</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator==_id1510115"></a><span class="keyword">operator</span><span class="special">==</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator!=_id1510158"></a><span class="keyword">operator</span><span class="special">!=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator!=_id1510201"></a><span class="keyword">operator</span><span class="special">!=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator!=_id1510243"></a><span class="keyword">operator</span><span class="special">!=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator!=_id1510286"></a><span class="keyword">operator</span><span class="special">!=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510329"></a><span class="keyword">operator</span><span class="special">||</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510371"></a><span class="keyword">operator</span><span class="special">||</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510414"></a><span class="keyword">operator</span><span class="special">||</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510457"></a><span class="keyword">operator</span><span class="special">||</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&&_id1510499"></a><span class="keyword">operator</span><span class="special">&&</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&&_id1510542"></a><span class="keyword">operator</span><span class="special">&&</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&&_id1510585"></a><span class="keyword">operator</span><span class="special">&&</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&&_id1510627"></a><span class="keyword">operator</span><span class="special">&&</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&_id1510670"></a><span class="keyword">operator</span><span class="special">&</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&_id1510713"></a><span class="keyword">operator</span><span class="special">&</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&_id1510755"></a><span class="keyword">operator</span><span class="special">&</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&_id1510798"></a><span class="keyword">operator</span><span class="special">&</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510841"></a><span class="keyword">operator</span><span class="special">|</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510883"></a><span class="keyword">operator</span><span class="special">|</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510926"></a><span class="keyword">operator</span><span class="special">|</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_id1510969"></a><span class="keyword">operator</span><span class="special">|</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E_id1511011"></a><span class="keyword">operator</span><span class="special">^</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E_id1511054"></a><span class="keyword">operator</span><span class="special">^</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E_id1511097"></a><span class="keyword">operator</span><span class="special">^</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E_id1511139"></a><span class="keyword">operator</span><span class="special">^</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator,_id1511182"></a><span class="keyword">operator</span><span class="special">,</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator,_id1511225"></a><span class="keyword">operator</span><span class="special">,</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator,_id1511267"></a><span class="keyword">operator</span><span class="special">,</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator,_id1511310"></a><span class="keyword">operator</span><span class="special">,</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1511353"></a><span class="keyword">operator</span><span class="special">->*</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1511395"></a><span class="keyword">operator</span><span class="special">->*</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1511438"></a><span class="keyword">operator</span><span class="special">->*</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-_id1511481"></a><span class="keyword">operator</span><span class="special">->*</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511523"></a><span class="keyword">operator</span><span class="special"><<=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511566"></a><span class="keyword">operator</span><span class="special"><<=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511609"></a><span class="keyword">operator</span><span class="special"><<=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511651"></a><span class="keyword">operator</span><span class="special"><<=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511694"></a><span class="keyword">operator</span><span class="special">>>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511737"></a><span class="keyword">operator</span><span class="special">>>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511779"></a><span class="keyword">operator</span><span class="special">>>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511822"></a><span class="keyword">operator</span><span class="special">>>=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511865"></a><span class="keyword">operator</span><span class="special">*=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511907"></a><span class="keyword">operator</span><span class="special">*=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511950"></a><span class="keyword">operator</span><span class="special">*=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1511993"></a><span class="keyword">operator</span><span class="special">*=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/=_id1512035"></a><span class="keyword">operator</span><span class="special">/=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/=_id1512078"></a><span class="keyword">operator</span><span class="special">/=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/=_id1512121"></a><span class="keyword">operator</span><span class="special">/=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator/=_id1512163"></a><span class="keyword">operator</span><span class="special">/=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%=_id1512206"></a><span class="keyword">operator</span><span class="special">%=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%=_id1512249"></a><span class="keyword">operator</span><span class="special">%=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%=_id1512291"></a><span class="keyword">operator</span><span class="special">%=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%=_id1512334"></a><span class="keyword">operator</span><span class="special">%=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+=_id1512377"></a><span class="keyword">operator</span><span class="special">+=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+=_id1512419"></a><span class="keyword">operator</span><span class="special">+=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+=_id1512462"></a><span class="keyword">operator</span><span class="special">+=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator+=_id1512505"></a><span class="keyword">operator</span><span class="special">+=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-=_id1512547"></a><span class="keyword">operator</span><span class="special">-=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-=_id1512590"></a><span class="keyword">operator</span><span class="special">-=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-=_id1512633"></a><span class="keyword">operator</span><span class="special">-=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator-=_id1512675"></a><span class="keyword">operator</span><span class="special">-=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&=_id1512718"></a><span class="keyword">operator</span><span class="special">&=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&=_id1512761"></a><span class="keyword">operator</span><span class="special">&=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&=_id1512803"></a><span class="keyword">operator</span><span class="special">&=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator&=_id1512846"></a><span class="keyword">operator</span><span class="special">&=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1512889"></a><span class="keyword">operator</span><span class="special">|=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1512931"></a><span class="keyword">operator</span><span class="special">|=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1512974"></a><span class="keyword">operator</span><span class="special">|=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator_=_id1513017"></a><span class="keyword">operator</span><span class="special">|=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E=_id1513059"></a><span class="keyword">operator</span><span class="special">^=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E=_id1513102"></a><span class="keyword">operator</span><span class="special">^=</span><span class="special">(</span><span class="identifier">Left</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E=_id1513145"></a><span class="keyword">operator</span><span class="special">^=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Left<span class="special">,</span> <span class="keyword">typename</span> Right<span class="special">></span> + <span class="emphasis"><em><span class="identifier">unspecified</span></em></span> <a name="boost.proto.operator%5E=_id1513187"></a><span class="keyword">operator</span><span class="special">^=</span><span class="special">(</span><span class="identifier">Left</span> <span class="keyword">const</span> <span class="special">&</span> left<span class="special">,</span> <span class="identifier">Right</span> <span class="keyword">const</span> <span class="special">&</span> right<span class="special">)</span><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> A0<span class="special">,</span> <span class="keyword">typename</span> A1<span class="special">,</span> <span class="keyword">typename</span> A2<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/make_expr.html" title="Struct template make_expr">proto::result_of::make_expr</a><span class="special"><</span> + <a class="link" href="../boost/proto/tag/if_else_.html" title="Struct if_else_">proto::tag::if_else_</a><span class="special">,</span> + <a class="link" href="../boost/proto/deduce_domain.html" title="Struct deduce_domain">proto::deduce_domain</a><span class="special">,</span> + <span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">,</span> + <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">,</span> + <span class="identifier">A2</span> <span class="keyword">const</span> <span class="special">&</span> + <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> + <a name="boost.proto.if_else"></a><span class="identifier">if_else</span><span class="special">(</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&</span> a0<span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&</span> a1<span class="special">,</span> <span class="identifier">A2</span> <span class="keyword">const</span> <span class="special">&</span> a2<span class="special">)</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.proto_hpp"></a>Header <<a href="../../../boost/proto/proto.hpp" target="_top">boost/proto/proto.hpp</a>></h3></div></div></div> +<p>Includes all of Proto, except the Boost.Typeof registrations.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.proto_fwd_hpp"></a>Header <<a href="../../../boost/proto/proto_fwd.hpp" target="_top">boost/proto/proto_fwd.hpp</a>></h3></div></div></div> +<p>Forward declarations of all of proto's public types and functions. </p> +<pre class="synopsis"> + +<a class="link" href="../BOOST_PROTO_MAX_ARITY.html" title="Macro BOOST_PROTO_MAX_ARITY">BOOST_PROTO_MAX_ARITY</a> +<a class="link" href="../BOOST_PROTO_MAX_LOGICAL_ARITY.html" title="Macro BOOST_PROTO_MAX_LOGICAL_ARITY">BOOST_PROTO_MAX_LOGICAL_ARITY</a> +<a class="link" href="../BOOST_PROTO_MAX_FUNCTION_CALL_ARITY.html" title="Macro BOOST_PROTO_MAX_FUNCTION_CALL_ARITY">BOOST_PROTO_MAX_FUNCTION_CALL_ARITY</a></pre> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/callable.html" title="Struct callable">callable</a><span class="special">;</span> + + <span class="keyword">int</span> <span class="keyword">const</span> <a class="link" href="../boost/proto/N.html" title="Global N">N</a><span class="special">;</span> + + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/flatten.html" title="Struct flatten">proto::functional::flatten</a> <a name="boost.proto._flatten"></a><span class="identifier">_flatten</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_pair.html" title="Struct make_pair">proto::functional::make_pair</a> <a name="boost.proto._make_pair"></a><span class="identifier">_make_pair</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/first.html" title="Struct first">proto::functional::first</a> <a name="boost.proto._first"></a><span class="identifier">_first</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/second.html" title="Struct second">proto::functional::second</a> <a name="boost.proto._second"></a><span class="identifier">_second</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/pop_back.html" title="Struct pop_back">proto::functional::pop_back</a> <a name="boost.proto._pop_back"></a><span class="identifier">_pop_back</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/pop_front.html" title="Struct pop_front">proto::functional::pop_front</a> <a name="boost.proto._pop_front"></a><span class="identifier">_pop_front</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/push_back.html" title="Struct push_back">proto::functional::push_back</a> <a name="boost.proto._push_back"></a><span class="identifier">_push_back</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/push_front.html" title="Struct push_front">proto::functional::push_front</a> <a name="boost.proto._push_front"></a><span class="identifier">_push_front</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/reverse.html" title="Struct reverse">proto::functional::reverse</a> <a name="boost.proto._reverse"></a><span class="identifier">_reverse</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/eval.html" title="Struct eval">proto::functional::eval</a> <a name="boost.proto._eval"></a><span class="identifier">_eval</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/deep_copy.html" title="Struct deep_copy">proto::functional::deep_copy</a> <a name="boost.proto._deep_copy"></a><span class="identifier">_deep_copy</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/terminal.html" title="Struct terminal">proto::tag::terminal</a> <span class="special">></span> <a name="boost.proto._make_terminal"></a><span class="identifier">_make_terminal</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/unary_plus.html" title="Struct unary_plus">proto::tag::unary_plus</a> <span class="special">></span> <a name="boost.proto._make_unary_plus"></a><span class="identifier">_make_unary_plus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/negate.html" title="Struct negate">proto::tag::negate</a> <span class="special">></span> <a name="boost.proto._make_negate"></a><span class="identifier">_make_negate</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/dereference.html" title="Struct dereference">proto::tag::dereference</a> <span class="special">></span> <a name="boost.proto._make_dereference"></a><span class="identifier">_make_dereference</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/complement.html" title="Struct complement">proto::tag::complement</a> <span class="special">></span> <a name="boost.proto._make_complement"></a><span class="identifier">_make_complement</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/address_of.html" title="Struct address_of">proto::tag::address_of</a> <span class="special">></span> <a name="boost.proto._make_address_of"></a><span class="identifier">_make_address_of</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/logical_not.html" title="Struct logical_not">proto::tag::logical_not</a> <span class="special">></span> <a name="boost.proto._make_logical_not"></a><span class="identifier">_make_logical_not</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/pre_inc.html" title="Struct pre_inc">proto::tag::pre_inc</a> <span class="special">></span> <a name="boost.proto._make_pre_inc"></a><span class="identifier">_make_pre_inc</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/pre_dec.html" title="Struct pre_dec">proto::tag::pre_dec</a> <span class="special">></span> <a name="boost.proto._make_pre_dec"></a><span class="identifier">_make_pre_dec</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/post_inc.html" title="Struct post_inc">proto::tag::post_inc</a> <span class="special">></span> <a name="boost.proto._make_post_inc"></a><span class="identifier">_make_post_inc</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/post_dec.html" title="Struct post_dec">proto::tag::post_dec</a> <span class="special">></span> <a name="boost.proto._make_post_dec"></a><span class="identifier">_make_post_dec</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_left.html" title="Struct shift_left">proto::tag::shift_left</a> <span class="special">></span> <a name="boost.proto._make_shift_left"></a><span class="identifier">_make_shift_left</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_right.html" title="Struct shift_right">proto::tag::shift_right</a> <span class="special">></span> <a name="boost.proto._make_shift_right"></a><span class="identifier">_make_shift_right</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/multiplies.html" title="Struct multiplies">proto::tag::multiplies</a> <span class="special">></span> <a name="boost.proto._make_multiplies"></a><span class="identifier">_make_multiplies</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/divides.html" title="Struct divides">proto::tag::divides</a> <span class="special">></span> <a name="boost.proto._make_divides"></a><span class="identifier">_make_divides</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/modulus.html" title="Struct modulus">proto::tag::modulus</a> <span class="special">></span> <a name="boost.proto._make_modulus"></a><span class="identifier">_make_modulus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/plus.html" title="Struct plus">proto::tag::plus</a> <span class="special">></span> <a name="boost.proto._make_plus"></a><span class="identifier">_make_plus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/minus.html" title="Struct minus">proto::tag::minus</a> <span class="special">></span> <a name="boost.proto._make_minus"></a><span class="identifier">_make_minus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/less.html" title="Struct less">proto::tag::less</a> <span class="special">></span> <a name="boost.proto._make_less"></a><span class="identifier">_make_less</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/greater.html" title="Struct greater">proto::tag::greater</a> <span class="special">></span> <a name="boost.proto._make_greater"></a><span class="identifier">_make_greater</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/less_equal.html" title="Struct less_equal">proto::tag::less_equal</a> <span class="special">></span> <a name="boost.proto._make_less_equal"></a><span class="identifier">_make_less_equal</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/greater_equal.html" title="Struct greater_equal">proto::tag::greater_equal</a> <span class="special">></span> <a name="boost.proto._make_greater_equal"></a><span class="identifier">_make_greater_equal</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/equal_to.html" title="Struct equal_to">proto::tag::equal_to</a> <span class="special">></span> <a name="boost.proto._make_equal_to"></a><span class="identifier">_make_equal_to</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/not_equal_to.html" title="Struct not_equal_to">proto::tag::not_equal_to</a> <span class="special">></span> <a name="boost.proto._make_not_equal_to"></a><span class="identifier">_make_not_equal_to</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/logical_or.html" title="Struct logical_or">proto::tag::logical_or</a> <span class="special">></span> <a name="boost.proto._make_logical_or"></a><span class="identifier">_make_logical_or</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/logical_and.html" title="Struct logical_and">proto::tag::logical_and</a> <span class="special">></span> <a name="boost.proto._make_logical_and"></a><span class="identifier">_make_logical_and</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_and.html" title="Struct bitwise_and">proto::tag::bitwise_and</a> <span class="special">></span> <a name="boost.proto._make_bitwise_and"></a><span class="identifier">_make_bitwise_and</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_or.html" title="Struct bitwise_or">proto::tag::bitwise_or</a> <span class="special">></span> <a name="boost.proto._make_bitwise_or"></a><span class="identifier">_make_bitwise_or</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_xor.html" title="Struct bitwise_xor">proto::tag::bitwise_xor</a> <span class="special">></span> <a name="boost.proto._make_bitwise_xor"></a><span class="identifier">_make_bitwise_xor</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/comma.html" title="Struct comma">proto::tag::comma</a> <span class="special">></span> <a name="boost.proto._make_comma"></a><span class="identifier">_make_comma</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/mem_ptr.html" title="Struct mem_ptr">proto::tag::mem_ptr</a> <span class="special">></span> <a name="boost.proto._make_mem_ptr"></a><span class="identifier">_make_mem_ptr</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/assign.html" title="Struct assign">proto::tag::assign</a> <span class="special">></span> <a name="boost.proto._make_assign"></a><span class="identifier">_make_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_left_assign.html" title="Struct shift_left_assign">proto::tag::shift_left_assign</a> <span class="special">></span> <a name="boost.proto._make_shift_left_assign"></a><span class="identifier">_make_shift_left_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_right_assign.html" title="Struct shift_right_assign">proto::tag::shift_right_assign</a> <span class="special">></span> <a name="boost.proto._make_shift_right_assign"></a><span class="identifier">_make_shift_right_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/multiplies_assign.html" title="Struct multiplies_assign">proto::tag::multiplies_assign</a> <span class="special">></span> <a name="boost.proto._make_multiplies_assign"></a><span class="identifier">_make_multiplies_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/divides_assign.html" title="Struct divides_assign">proto::tag::divides_assign</a> <span class="special">></span> <a name="boost.proto._make_divides_assign"></a><span class="identifier">_make_divides_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/modulus_assign.html" title="Struct modulus_assign">proto::tag::modulus_assign</a> <span class="special">></span> <a name="boost.proto._make_modulus_assign"></a><span class="identifier">_make_modulus_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/plus_assign.html" title="Struct plus_assign">proto::tag::plus_assign</a> <span class="special">></span> <a name="boost.proto._make_plus_assign"></a><span class="identifier">_make_plus_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/minus_assign.html" title="Struct minus_assign">proto::tag::minus_assign</a> <span class="special">></span> <a name="boost.proto._make_minus_assign"></a><span class="identifier">_make_minus_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_and_assign.html" title="Struct bitwise_and_assign">proto::tag::bitwise_and_assign</a> <span class="special">></span> <a name="boost.proto._make_bitwise_and_assign"></a><span class="identifier">_make_bitwise_and_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_or_assign.html" title="Struct bitwise_or_assign">proto::tag::bitwise_or_assign</a> <span class="special">></span> <a name="boost.proto._make_bitwise_or_assign"></a><span class="identifier">_make_bitwise_or_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_xor_assign.html" title="Struct bitwise_xor_assign">proto::tag::bitwise_xor_assign</a> <span class="special">></span> <a name="boost.proto._make_bitwise_xor_assign"></a><span class="identifier">_make_bitwise_xor_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/subscript.html" title="Struct subscript">proto::tag::subscript</a> <span class="special">></span> <a name="boost.proto._make_subscript"></a><span class="identifier">_make_subscript</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/if_else_.html" title="Struct if_else_">proto::tag::if_else_</a> <span class="special">></span> <a name="boost.proto._make_if_else"></a><span class="identifier">_make_if_else</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/function.html" title="Struct function">proto::tag::function</a> <span class="special">></span> <a name="boost.proto._make_function"></a><span class="identifier">_make_function</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/_child_c.html" title="Struct template _child_c">proto::_child_c</a><span class="special"><</span> <em class="replaceable"><code><span class="identifier">N</span></code></em> <span class="special">></span> <a name="boost.proto._childN"></a><span class="identifier">_childN</span><span class="special">;</span> <span class="comment">// For each <em class="replaceable"><code>N</code></em> in <code class="computeroutput">[0,BOOST_PROTO_MAX_ARITY)</code></span> + <span class="keyword">typedef</span> <a class="link" href="reference.html#boost.proto._childN">proto::_child0</a> <a name="boost.proto._child"></a><span class="identifier">_child</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="reference.html#boost.proto._childN">proto::_child0</a> <a name="boost.proto._left"></a><span class="identifier">_left</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="reference.html#boost.proto._childN">proto::_child1</a> <a name="boost.proto._right"></a><span class="identifier">_right</span><span class="special">;</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/terminal.html" title="Struct terminal">proto::tag::terminal</a> <span class="special">></span> <a name="boost.proto.functional.make_terminal"></a><span class="identifier">make_terminal</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/unary_plus.html" title="Struct unary_plus">proto::tag::unary_plus</a> <span class="special">></span> <a name="boost.proto.functional.make_unary_plus"></a><span class="identifier">make_unary_plus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/negate.html" title="Struct negate">proto::tag::negate</a> <span class="special">></span> <a name="boost.proto.functional.make_negate"></a><span class="identifier">make_negate</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/dereference.html" title="Struct dereference">proto::tag::dereference</a> <span class="special">></span> <a name="boost.proto.functional.make_dereference"></a><span class="identifier">make_dereference</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/complement.html" title="Struct complement">proto::tag::complement</a> <span class="special">></span> <a name="boost.proto.functional.make_complement"></a><span class="identifier">make_complement</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/address_of.html" title="Struct address_of">proto::tag::address_of</a> <span class="special">></span> <a name="boost.proto.functional.make_address_of"></a><span class="identifier">make_address_of</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/logical_not.html" title="Struct logical_not">proto::tag::logical_not</a> <span class="special">></span> <a name="boost.proto.functional.make_logical_not"></a><span class="identifier">make_logical_not</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/pre_inc.html" title="Struct pre_inc">proto::tag::pre_inc</a> <span class="special">></span> <a name="boost.proto.functional.make_pre_inc"></a><span class="identifier">make_pre_inc</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/pre_dec.html" title="Struct pre_dec">proto::tag::pre_dec</a> <span class="special">></span> <a name="boost.proto.functional.make_pre_dec"></a><span class="identifier">make_pre_dec</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/post_inc.html" title="Struct post_inc">proto::tag::post_inc</a> <span class="special">></span> <a name="boost.proto.functional.make_post_inc"></a><span class="identifier">make_post_inc</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/post_dec.html" title="Struct post_dec">proto::tag::post_dec</a> <span class="special">></span> <a name="boost.proto.functional.make_post_dec"></a><span class="identifier">make_post_dec</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_left.html" title="Struct shift_left">proto::tag::shift_left</a> <span class="special">></span> <a name="boost.proto.functional.make_shift_left"></a><span class="identifier">make_shift_left</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_right.html" title="Struct shift_right">proto::tag::shift_right</a> <span class="special">></span> <a name="boost.proto.functional.make_shift_right"></a><span class="identifier">make_shift_right</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/multiplies.html" title="Struct multiplies">proto::tag::multiplies</a> <span class="special">></span> <a name="boost.proto.functional.make_multiplies"></a><span class="identifier">make_multiplies</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/divides.html" title="Struct divides">proto::tag::divides</a> <span class="special">></span> <a name="boost.proto.functional.make_divides"></a><span class="identifier">make_divides</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/modulus.html" title="Struct modulus">proto::tag::modulus</a> <span class="special">></span> <a name="boost.proto.functional.make_modulus"></a><span class="identifier">make_modulus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/plus.html" title="Struct plus">proto::tag::plus</a> <span class="special">></span> <a name="boost.proto.functional.make_plus"></a><span class="identifier">make_plus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/minus.html" title="Struct minus">proto::tag::minus</a> <span class="special">></span> <a name="boost.proto.functional.make_minus"></a><span class="identifier">make_minus</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/less.html" title="Struct less">proto::tag::less</a> <span class="special">></span> <a name="boost.proto.functional.make_less"></a><span class="identifier">make_less</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/greater.html" title="Struct greater">proto::tag::greater</a> <span class="special">></span> <a name="boost.proto.functional.make_greater"></a><span class="identifier">make_greater</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/less_equal.html" title="Struct less_equal">proto::tag::less_equal</a> <span class="special">></span> <a name="boost.proto.functional.make_less_equal"></a><span class="identifier">make_less_equal</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/greater_equal.html" title="Struct greater_equal">proto::tag::greater_equal</a> <span class="special">></span> <a name="boost.proto.functional.make_greater_equal"></a><span class="identifier">make_greater_equal</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/equal_to.html" title="Struct equal_to">proto::tag::equal_to</a> <span class="special">></span> <a name="boost.proto.functional.make_equal_to"></a><span class="identifier">make_equal_to</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/not_equal_to.html" title="Struct not_equal_to">proto::tag::not_equal_to</a> <span class="special">></span> <a name="boost.proto.functional.make_not_equal_to"></a><span class="identifier">make_not_equal_to</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/logical_or.html" title="Struct logical_or">proto::tag::logical_or</a> <span class="special">></span> <a name="boost.proto.functional.make_logical_or"></a><span class="identifier">make_logical_or</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/logical_and.html" title="Struct logical_and">proto::tag::logical_and</a> <span class="special">></span> <a name="boost.proto.functional.make_logical_and"></a><span class="identifier">make_logical_and</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_and.html" title="Struct bitwise_and">proto::tag::bitwise_and</a> <span class="special">></span> <a name="boost.proto.functional.make_bitwise_and"></a><span class="identifier">make_bitwise_and</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_or.html" title="Struct bitwise_or">proto::tag::bitwise_or</a> <span class="special">></span> <a name="boost.proto.functional.make_bitwise_or"></a><span class="identifier">make_bitwise_or</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_xor.html" title="Struct bitwise_xor">proto::tag::bitwise_xor</a> <span class="special">></span> <a name="boost.proto.functional.make_bitwise_xor"></a><span class="identifier">make_bitwise_xor</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/comma.html" title="Struct comma">proto::tag::comma</a> <span class="special">></span> <a name="boost.proto.functional.make_comma"></a><span class="identifier">make_comma</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/mem_ptr.html" title="Struct mem_ptr">proto::tag::mem_ptr</a> <span class="special">></span> <a name="boost.proto.functional.make_mem_ptr"></a><span class="identifier">make_mem_ptr</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/assign.html" title="Struct assign">proto::tag::assign</a> <span class="special">></span> <a name="boost.proto.functional.make_assign"></a><span class="identifier">make_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_left_assign.html" title="Struct shift_left_assign">proto::tag::shift_left_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_shift_left_assign"></a><span class="identifier">make_shift_left_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/shift_right_assign.html" title="Struct shift_right_assign">proto::tag::shift_right_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_shift_right_assign"></a><span class="identifier">make_shift_right_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/multiplies_assign.html" title="Struct multiplies_assign">proto::tag::multiplies_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_multiplies_assign"></a><span class="identifier">make_multiplies_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/divides_assign.html" title="Struct divides_assign">proto::tag::divides_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_divides_assign"></a><span class="identifier">make_divides_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/modulus_assign.html" title="Struct modulus_assign">proto::tag::modulus_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_modulus_assign"></a><span class="identifier">make_modulus_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/plus_assign.html" title="Struct plus_assign">proto::tag::plus_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_plus_assign"></a><span class="identifier">make_plus_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/minus_assign.html" title="Struct minus_assign">proto::tag::minus_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_minus_assign"></a><span class="identifier">make_minus_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_and_assign.html" title="Struct bitwise_and_assign">proto::tag::bitwise_and_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_bitwise_and_assign"></a><span class="identifier">make_bitwise_and_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_or_assign.html" title="Struct bitwise_or_assign">proto::tag::bitwise_or_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_bitwise_or_assign"></a><span class="identifier">make_bitwise_or_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/bitwise_xor_assign.html" title="Struct bitwise_xor_assign">proto::tag::bitwise_xor_assign</a> <span class="special">></span> <a name="boost.proto.functional.make_bitwise_xor_assign"></a><span class="identifier">make_bitwise_xor_assign</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/subscript.html" title="Struct subscript">proto::tag::subscript</a> <span class="special">></span> <a name="boost.proto.functional.make_subscript"></a><span class="identifier">make_subscript</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/if_else_.html" title="Struct if_else_">proto::tag::if_else_</a> <span class="special">></span> <a name="boost.proto.functional.make_if_else"></a><span class="identifier">make_if_else</span><span class="special">;</span> + <span class="keyword">typedef</span> <a class="link" href="../boost/proto/functional/make_expr.html" title="Struct template make_expr">proto::functional::make_expr</a><span class="special"><</span> <a class="link" href="../boost/proto/tag/function.html" title="Struct function">proto::tag::function</a> <span class="special">></span> <a name="boost.proto.functional.make_function"></a><span class="identifier">make_function</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.proto_typeof_hpp"></a>Header <<a href="../../../boost/proto/proto_typeof.hpp" target="_top">boost/proto/proto_typeof.hpp</a>></h3></div></div></div> +<p>Boost.Typeof registrations for Proto's types, and definition of the + <code class="computeroutput"><a class="link" href="../BOOST_PROTO_AUTO.html" title="Macro BOOST_PROTO_AUTO">BOOST_PROTO_AUTO</a>()</code> macro.</p> +<pre class="synopsis"> + +<a class="link" href="../BOOST_PROTO_AUTO.html" title="Macro BOOST_PROTO_AUTO">BOOST_PROTO_AUTO</a>(Var, Expr)</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.repeat_hpp"></a>Header <<a href="../../../boost/proto/repeat.hpp" target="_top">boost/proto/repeat.hpp</a>></h3></div></div></div> +<p> + Contains macros to ease the generation of repetitious code constructs. + </p> +<pre class="synopsis"> + +<a class="link" href="../BOOST_PROTO_REPEAT.html" title="Macro BOOST_PROTO_REPEAT">BOOST_PROTO_REPEAT</a>(MACRO) +<a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO">BOOST_PROTO_REPEAT_FROM_TO</a>(FROM, TO, MACRO) +<a class="link" href="../BOOST_PROTO_REPEAT_EX.html" title="Macro BOOST_PROTO_REPEAT_EX">BOOST_PROTO_REPEAT_EX</a>(MACRO, typename_A, A, A_a, a) +<a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO_EX.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO_EX">BOOST_PROTO_REPEAT_FROM_TO_EX</a>(FROM, TO, MACRO, typename_A, A, A_a, a) +<a class="link" href="../BOOST_PROTO_LOCAL_ITERATE.html" title="Macro BOOST_PROTO_LOCAL_ITERATE">BOOST_PROTO_LOCAL_ITERATE</a>() +<a class="link" href="../BOOST_PROTO_typename_A.html" title="Macro BOOST_PROTO_typename_A">BOOST_PROTO_typename_A</a>(N) +<a class="link" href="../BOOST_PROTO_A_const_ref.html" title="Macro BOOST_PROTO_A_const_ref">BOOST_PROTO_A_const_ref</a>(N) +<a class="link" href="../BOOST_PROTO_A_ref.html" title="Macro BOOST_PROTO_A_ref">BOOST_PROTO_A_ref</a>(N) +<a class="link" href="../BOOST_PROTO_A_id1516642.html" title="Macro BOOST_PROTO_A">BOOST_PROTO_A</a>(N) +<a class="link" href="../BOOST_PROTO_A_const.html" title="Macro BOOST_PROTO_A_const">BOOST_PROTO_A_const</a>(N) +<a class="link" href="../BOOST_PROTO_A_const_ref_a.html" title="Macro BOOST_PROTO_A_const_ref_a">BOOST_PROTO_A_const_ref_a</a>(N) +<a class="link" href="../BOOST_PROTO_A_ref_a.html" title="Macro BOOST_PROTO_A_ref_a">BOOST_PROTO_A_ref_a</a>(N) +<a class="link" href="../BOOST_PROTO_ref_a.html" title="Macro BOOST_PROTO_ref_a">BOOST_PROTO_ref_a</a>(N) +<a class="link" href="../BOOST_PROTO_a_id1517101.html" title="Macro BOOST_PROTO_a">BOOST_PROTO_a</a>(N)</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.tags_hpp"></a>Header <<a href="../../../boost/proto/tags.hpp" target="_top">boost/proto/tags.hpp</a>></h3></div></div></div> +<p>Contains the tags for all the overloadable operators in C++ </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">tag</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/terminal.html" title="Struct terminal">terminal</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/unary_plus.html" title="Struct unary_plus">unary_plus</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/negate.html" title="Struct negate">negate</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/dereference.html" title="Struct dereference">dereference</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/complement.html" title="Struct complement">complement</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/address_of.html" title="Struct address_of">address_of</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/logical_not.html" title="Struct logical_not">logical_not</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/pre_inc.html" title="Struct pre_inc">pre_inc</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/pre_dec.html" title="Struct pre_dec">pre_dec</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/post_inc.html" title="Struct post_inc">post_inc</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/post_dec.html" title="Struct post_dec">post_dec</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/shift_left.html" title="Struct shift_left">shift_left</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/shift_right.html" title="Struct shift_right">shift_right</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/multiplies.html" title="Struct multiplies">multiplies</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/divides.html" title="Struct divides">divides</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/modulus.html" title="Struct modulus">modulus</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/plus.html" title="Struct plus">plus</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/minus.html" title="Struct minus">minus</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/less.html" title="Struct less">less</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/greater.html" title="Struct greater">greater</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/less_equal.html" title="Struct less_equal">less_equal</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/greater_equal.html" title="Struct greater_equal">greater_equal</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/equal_to.html" title="Struct equal_to">equal_to</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/not_equal_to.html" title="Struct not_equal_to">not_equal_to</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/logical_or.html" title="Struct logical_or">logical_or</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/logical_and.html" title="Struct logical_and">logical_and</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/bitwise_and.html" title="Struct bitwise_and">bitwise_and</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/bitwise_or.html" title="Struct bitwise_or">bitwise_or</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/bitwise_xor.html" title="Struct bitwise_xor">bitwise_xor</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/comma.html" title="Struct comma">comma</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/mem_ptr.html" title="Struct mem_ptr">mem_ptr</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/assign.html" title="Struct assign">assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/shift_left_assign.html" title="Struct shift_left_assign">shift_left_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/shift_right_assign.html" title="Struct shift_right_assign">shift_right_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/multiplies_assign.html" title="Struct multiplies_assign">multiplies_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/divides_assign.html" title="Struct divides_assign">divides_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/modulus_assign.html" title="Struct modulus_assign">modulus_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/plus_assign.html" title="Struct plus_assign">plus_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/minus_assign.html" title="Struct minus_assign">minus_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/bitwise_and_assign.html" title="Struct bitwise_and_assign">bitwise_and_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/bitwise_or_assign.html" title="Struct bitwise_or_assign">bitwise_or_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/bitwise_xor_assign.html" title="Struct bitwise_xor_assign">bitwise_xor_assign</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/subscript.html" title="Struct subscript">subscript</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/if_else_.html" title="Struct if_else_">if_else_</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag/function.html" title="Struct function">function</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.traits_hpp"></a>Header <<a href="../../../boost/proto/traits.hpp" target="_top">boost/proto/traits.hpp</a>></h3></div></div></div> +<p> + Contains definitions for various expression traits and utilities like + <code class="computeroutput"><a class="link" href="../boost/proto/tag_of.html" title="Struct template tag_of">proto::tag_of</a><></code> and + <code class="computeroutput"><a class="link" href="../boost/proto/arity_of.html" title="Struct template arity_of">proto::arity_of</a><></code>; + the functions + <code class="computeroutput"><a class="link" href="../boost/proto/value_id1528169.html" title="Function value">proto::value</a>()</code>, + <code class="computeroutput"><a class="link" href="../boost/proto/left_id1528275.html" title="Function left">proto::left</a>()</code> and + <code class="computeroutput"><a class="link" href="../boost/proto/right_id1528399.html" title="Function right">proto::right</a>()</code>; + <code class="computeroutput"><a class="link" href="../boost/proto/child_id1527766.html" title="Function child">proto::child</a>()</code>, + <code class="computeroutput"><a class="link" href="../boost/proto/child_c_id1528008.html" title="Function child_c">proto::child_c</a>()</code>, + <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr</a>()</code>, + <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child</a>()</code>, + and assorted helpers. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_callable.html" title="Struct template is_callable">is_callable</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_transform.html" title="Struct template is_transform">is_transform</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_aggregate.html" title="Struct template is_aggregate">is_aggregate</a><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">terminal</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">,</span> <span class="keyword">typename</span> V<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/if_else_.html" title="Struct template if_else_">if_else_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/unary_plus.html" title="Struct template unary_plus">unary_plus</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/negate.html" title="Struct template negate">negate</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/dereference.html" title="Struct template dereference">dereference</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/complement.html" title="Struct template complement">complement</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/address_of.html" title="Struct template address_of">address_of</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/logical_not.html" title="Struct template logical_not">logical_not</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/pre_inc.html" title="Struct template pre_inc">pre_inc</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/pre_dec.html" title="Struct template pre_dec">pre_dec</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/post_inc.html" title="Struct template post_inc">post_inc</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/post_dec.html" title="Struct template post_dec">post_dec</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/shift_left.html" title="Struct template shift_left">shift_left</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/shift_right.html" title="Struct template shift_right">shift_right</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/multiplies.html" title="Struct template multiplies">multiplies</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/divides.html" title="Struct template divides">divides</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/modulus.html" title="Struct template modulus">modulus</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/plus.html" title="Struct template plus">plus</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/minus.html" title="Struct template minus">minus</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/less.html" title="Struct template less">less</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/greater.html" title="Struct template greater">greater</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/less_equal.html" title="Struct template less_equal">less_equal</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/greater_equal.html" title="Struct template greater_equal">greater_equal</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/equal_to.html" title="Struct template equal_to">equal_to</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/not_equal_to.html" title="Struct template not_equal_to">not_equal_to</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/logical_or.html" title="Struct template logical_or">logical_or</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/logical_and.html" title="Struct template logical_and">logical_and</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/bitwise_and.html" title="Struct template bitwise_and">bitwise_and</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/bitwise_or.html" title="Struct template bitwise_or">bitwise_or</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/bitwise_xor.html" title="Struct template bitwise_xor">bitwise_xor</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/comma.html" title="Struct template comma">comma</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/mem_ptr.html" title="Struct template mem_ptr">mem_ptr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/assign.html" title="Struct template assign">assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/shift_left_assign.html" title="Struct template shift_left_assign">shift_left_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/shift_right_assign.html" title="Struct template shift_right_assign">shift_right_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/multiplies_assign.html" title="Struct template multiplies_assign">multiplies_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/divides_assign.html" title="Struct template divides_assign">divides_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/modulus_assign.html" title="Struct template modulus_assign">modulus_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/plus_assign.html" title="Struct template plus_assign">plus_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/minus_assign.html" title="Struct template minus_assign">minus_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/bitwise_and_assign.html" title="Struct template bitwise_and_assign">bitwise_and_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/bitwise_or_assign.html" title="Struct template bitwise_or_assign">bitwise_or_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/bitwise_xor_assign.html" title="Struct template bitwise_xor_assign">bitwise_xor_assign</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/subscript.html" title="Struct template subscript">subscript</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/function.html" title="Struct template function">function</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/nullary_expr.html" title="Struct template nullary_expr">nullary_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/unary_expr.html" title="Struct template unary_expr">unary_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> U<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/binary_expr.html" title="Struct template binary_expr">binary_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Tag<span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/nary_expr.html" title="Struct template nary_expr">nary_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/is_expr.html" title="Struct template is_expr">is_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/tag_of.html" title="Struct template tag_of">tag_of</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/arity_of.html" title="Struct template arity_of">arity_of</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_expr.html" title="Struct template as_expr">proto::result_of::as_expr</a><span class="special"><</span> <span class="identifier">T</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr"><span class="identifier">as_expr</span></a><span class="special">(</span><span class="identifier">T</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> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_expr.html" title="Struct template as_expr">proto::result_of::as_expr</a><span class="special"><</span> <span class="identifier">T</span> <span class="keyword">const</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr"><span class="identifier">as_expr</span></a><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</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> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_expr.html" title="Struct template as_expr">proto::result_of::as_expr</a><span class="special"><</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">Domain</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr"><span class="identifier">as_expr</span></a><span class="special">(</span><span class="identifier">T</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> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_expr.html" title="Struct template as_expr">proto::result_of::as_expr</a><span class="special"><</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">Domain</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr"><span class="identifier">as_expr</span></a><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</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> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_child.html" title="Struct template as_child">proto::result_of::as_child</a><span class="special"><</span> <span class="identifier">T</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child"><span class="identifier">as_child</span></a><span class="special">(</span><span class="identifier">T</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> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_child.html" title="Struct template as_child">proto::result_of::as_child</a><span class="special"><</span> <span class="identifier">T</span> <span class="keyword">const</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child"><span class="identifier">as_child</span></a><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</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> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_child.html" title="Struct template as_child">proto::result_of::as_child</a><span class="special"><</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">Domain</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child"><span class="identifier">as_child</span></a><span class="special">(</span><span class="identifier">T</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> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a><span class="special">,</span> <span class="keyword">typename</span> T<span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/as_child.html" title="Struct template as_child">proto::result_of::as_child</a><span class="special"><</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">Domain</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child"><span class="identifier">as_child</span></a><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</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> N<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">proto::result_of::child</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">N</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/child_id1527766.html" title="Function child"><span class="identifier">child</span></a><span class="special">(</span><span class="identifier">Expr</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> N<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">proto::result_of::child</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">N</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/child_id1527766.html" title="Function child"><span class="identifier">child</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">proto::result_of::child</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/child_id1527766.html" title="Function child"><span class="identifier">child</span></a><span class="special">(</span><span class="identifier">Expr</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">proto::result_of::child</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/child_id1527766.html" title="Function child"><span class="identifier">child</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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">long</span> N<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">proto::result_of::child_c</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">N</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/child_c_id1528008.html" title="Function child_c"><span class="identifier">child_c</span></a><span class="special">(</span><span class="identifier">Expr</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">long</span> N<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">proto::result_of::child_c</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">,</span> <span class="identifier">N</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/child_c_id1528008.html" title="Function child_c"><span class="identifier">child_c</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/value.html" title="Struct template value">proto::result_of::value</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/value_id1528169.html" title="Function value"><span class="identifier">value</span></a><span class="special">(</span><span class="identifier">Expr</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/value.html" title="Struct template value">proto::result_of::value</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/value_id1528169.html" title="Function value"><span class="identifier">value</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/left.html" title="Struct template left">proto::result_of::left</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/left_id1528275.html" title="Function left"><span class="identifier">left</span></a><span class="special">(</span><span class="identifier">Expr</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/left.html" title="Struct template left">proto::result_of::left</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/left_id1528275.html" title="Function left"><span class="identifier">left</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/right.html" title="Struct template right">proto::result_of::right</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> <a class="link" href="../boost/proto/right_id1528399.html" title="Function right"><span class="identifier">right</span></a><span class="special">(</span><span class="identifier">Expr</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> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> + <span class="keyword">typename</span> <a class="link" href="../boost/proto/result_of/right.html" title="Struct template right">proto::result_of::right</a><span class="special"><</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="special">></span><span class="special">::</span><span class="identifier">type</span> + <a class="link" href="../boost/proto/right_id1528399.html" title="Function right"><span class="identifier">right</span></a><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="special">)</span><span class="special">;</span> + <span class="keyword">namespace</span> <span class="identifier">functional</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/as_expr.html" title="Struct template as_expr">as_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/as_child.html" title="Struct template as_child">as_child</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">long</span> N<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/child_c.html" title="Struct template child_c">child_c</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> N <span class="special">=</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">long_</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/child.html" title="Struct template child">child</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/value.html" title="Struct value">value</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/left.html" title="Struct left">left</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/functional/right.html" title="Struct right">right</a><span class="special">;</span> + <span class="special">}</span> + <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> T<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/as_expr.html" title="Struct template as_expr">as_expr</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../Domain.html" title="Concept Domain">Domain</a> <span class="special">=</span> <a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/as_child.html" title="Struct template as_child">as_child</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> N <span class="special">=</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">long_</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">child</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/value.html" title="Struct template value">value</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/left.html" title="Struct template left">left</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/right.html" title="Struct template right">right</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">long</span> N<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">child_c</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform_hpp"></a>Header <<a href="../../../boost/proto/transform.hpp" target="_top">boost/proto/transform.hpp</a>></h3></div></div></div> +<p>Includes all the built-in transforms of Proto.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.arg_hpp"></a>Header <<a href="../../../boost/proto/transform/arg.hpp" target="_top">boost/proto/transform/arg.hpp</a>></h3></div></div></div> +<p>Contains definition of the childN transforms and friends.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_expr.html" title="Struct _expr">_expr</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_state.html" title="Struct _state">_state</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_data.html" title="Struct _data">_data</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> N<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/_child_c.html" title="Struct template _child_c">_child_c</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_value.html" title="Struct _value">_value</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_void.html" title="Struct _void">_void</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_byref.html" title="Struct _byref">_byref</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/_byval.html" title="Struct _byval">_byval</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.call_hpp"></a>Header <<a href="../../../boost/proto/transform/call.hpp" target="_top">boost/proto/transform/call.hpp</a>></h3></div></div></div> +<p>Contains definition of the call<> transform. </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/call.html" title="Struct template call">call</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.default_hpp"></a>Header <<a href="../../../boost/proto/transform/default.hpp" target="_top">boost/proto/transform/default.hpp</a>></h3></div></div></div> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar <span class="special">=</span> <em class="replaceable"><code><span class="identifier">unspecified</span></code></em><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/_default.html" title="Struct template _default">_default</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.fold_hpp"></a>Header <<a href="../../../boost/proto/transform/fold.hpp" target="_top">boost/proto/transform/fold.hpp</a>></h3></div></div></div> +<p>Contains definition of the + <code class="computeroutput"> + <a class="link" href="../boost/proto/fold.html" title="Struct template fold">proto::fold<></a> + </code> and + <code class="computeroutput"> + <a class="link" href="../boost/proto/reverse_fold.html" title="Struct template reverse_fold">proto::reverse_fold<></a> + </code> + transforms.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Sequence<span class="special">,</span> <span class="keyword">typename</span> State0<span class="special">,</span> <span class="keyword">typename</span> Fun<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/fold.html" title="Struct template fold">fold</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Sequence<span class="special">,</span> <span class="keyword">typename</span> State0<span class="special">,</span> <span class="keyword">typename</span> Fun<span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/reverse_fold.html" title="Struct template reverse_fold">reverse_fold</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.fold_tree_hpp"></a>Header <<a href="../../../boost/proto/transform/fold_tree.hpp" target="_top">boost/proto/transform/fold_tree.hpp</a>></h3></div></div></div> +<p> + Contains definition of the + <code class="computeroutput"> + <a class="link" href="../boost/proto/fold_tree.html" title="Struct template fold_tree">proto::fold_tree<></a> + </code> and + <code class="computeroutput"> + <a class="link" href="../boost/proto/reverse_fold_tree.html" title="Struct template reverse_fold_tree">proto::reverse_fold_tree<></a> + </code> + transforms. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Sequence<span class="special">,</span> <span class="keyword">typename</span> State0<span class="special">,</span> <span class="keyword">typename</span> Fun<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/fold_tree.html" title="Struct template fold_tree">fold_tree</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Sequence<span class="special">,</span> <span class="keyword">typename</span> State0<span class="special">,</span> <span class="keyword">typename</span> Fun<span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/reverse_fold_tree.html" title="Struct template reverse_fold_tree">reverse_fold_tree</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.impl_hpp"></a>Header <<a href="../../../boost/proto/transform/impl.hpp" target="_top">boost/proto/transform/impl.hpp</a>></h3></div></div></div> +<p>Contains definition of transform<> and transform_impl<> helpers. </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../PrimitiveTransform.html" title="Concept PrimitiveTransform">PrimitiveTransform</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/transform.html" title="Struct template transform">transform</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> State<span class="special">,</span> <span class="keyword">typename</span> Data<span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/transform_impl.html" title="Struct template transform_impl">transform_impl</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.integral_c_hpp"></a>Header <<a href="../../../boost/proto/transform/integral_c.hpp" target="_top">boost/proto/transform/integral_c.hpp</a>></h3></div></div></div> +<p>Contains definition of the integral_c transform and friends.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">,</span> <span class="identifier">T</span> I<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/integral_c.html" title="Struct template integral_c">integral_c</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">char</span> I<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/char_.html" title="Struct template char_">char_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> I<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/int_.html" title="Struct template int_">int_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">long</span> I<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/long_.html" title="Struct template long_">long_</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> I<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/size_t.html" title="Struct template size_t">size_t</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.lazy_hpp"></a>Header <<a href="../../../boost/proto/transform/lazy.hpp" target="_top">boost/proto/transform/lazy.hpp</a>></h3></div></div></div> +<p> + Contains definition of the + <code class="computeroutput"> + <a class="link" href="../boost/proto/lazy.html" title="Struct template lazy">proto::lazy<></a> + </code> transform. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/lazy.html" title="Struct template lazy">lazy</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.make_hpp"></a>Header <<a href="../../../boost/proto/transform/make.hpp" target="_top">boost/proto/transform/make.hpp</a>></h3></div></div></div> +<p> + Contains definition of the + <code class="computeroutput"> + <a class="link" href="../boost/proto/make.html" title="Struct template make">proto::make<></a> + </code> + and + <code class="computeroutput"> + <a class="link" href="../boost/proto/protect.html" title="Struct template protect">proto::protect<></a> + </code> + transforms. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/noinvoke.html" title="Struct template noinvoke">noinvoke</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../PrimitiveTransform.html" title="Concept PrimitiveTransform">PrimitiveTransform</a><span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/protect.html" title="Struct template protect">protect</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> T<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/make.html" title="Struct template make">make</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.pass_through_hpp"></a>Header <<a href="../../../boost/proto/transform/pass_through.hpp" target="_top">boost/proto/transform/pass_through.hpp</a>></h3></div></div></div> +<p>Definition of the + <code class="computeroutput"><a class="link" href="../boost/proto/pass_through.html" title="Struct template pass_through">proto::pass_through<></a></code> + transform, which is the default transform of all of the expression generator metafunctions such as + <code class="computeroutput"><a class="link" href="../boost/proto/unary_plus.html" title="Struct template unary_plus">proto::unary_plus<></a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/plus.html" title="Struct template plus">proto::plus<></a></code> and + <code class="computeroutput"><a class="link" href="../boost/proto/nary_expr.html" title="Struct template nary_expr">proto::nary_expr<></a></code>.</p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/pass_through.html" title="Struct template pass_through">pass_through</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.transform.when_hpp"></a>Header <<a href="../../../boost/proto/transform/when.hpp" target="_top">boost/proto/transform/when.hpp</a>></h3></div></div></div> +<p> + Definition of the + <code class="computeroutput"> + <a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a> + </code> and + <code class="computeroutput"> + <a class="link" href="../boost/proto/otherwise.html" title="Struct template otherwise">proto::otherwise<></a> + </code> transforms. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar<span class="special">,</span> <span class="keyword">typename</span> <a class="link" href="../PrimitiveTransform.html" title="Concept PrimitiveTransform">PrimitiveTransform</a> <span class="special">=</span> <span class="identifier">Grammar</span><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/when.html" title="Struct template when">when</a><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar<span class="special">,</span> <span class="keyword">typename</span> Fun<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/when_Grammar__Fun_id1535641.html" title="Struct template when<Grammar, Fun *>">when</a><span class="special"><</span><span class="identifier">Grammar</span><span class="special">,</span> <span class="identifier">Fun</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> Grammar<span class="special">,</span> <span class="keyword">typename</span> R<span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> A<span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/when_Grammar__R_A___id1535725.html" title="Struct template when<Grammar, R(A...)>">when</a><span class="special"><</span><span class="identifier">Grammar</span><span class="special">,</span> <span class="identifier">R</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> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Grammar<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/when_Grammar__id1536082.html" title="Struct template when<Grammar, proto::external_transform>">when</a><span class="special"><</span><span class="identifier">Grammar</span><span class="special">,</span> <a class="link" href="../boost/proto/external_transform.html" title="Struct external_transform">proto::external_transform</a><span class="special">></span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Fun<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/otherwise.html" title="Struct template otherwise">otherwise</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/external_transform.html" title="Struct external_transform">external_transform</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span><span class="special">...</span> When<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/external_transforms.html" title="Struct template external_transforms">external_transforms</a><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.context_hpp"></a>Header <<a href="../../../boost/proto/context.hpp" target="_top">boost/proto/context.hpp</a>></h3></div></div></div> +<p>Includes all the built-in evaluation contexts of Proto.</p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.context.callable_hpp"></a>Header <<a href="../../../boost/proto/context/callable.hpp" target="_top">boost/proto/context/callable.hpp</a>></h3></div></div></div> +<p>Definintion of <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::context::callable_context<></a></code>, + an evaluation context for <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + that fans out each node and calls the derived context type with the expressions constituents. If the derived context + doesn't have an overload that handles this node, fall back to some other context. </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">context</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Context<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/context/callable_eval.html" title="Struct template callable_eval">callable_eval</a><span class="special">;</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> Context<span class="special">,</span> + <span class="keyword">typename</span> DefaultCtx <span class="special">=</span> <a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::context::default_context</a><span class="special">></span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">callable_context</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.context.default_hpp"></a>Header <<a href="../../../boost/proto/context/default.hpp" target="_top">boost/proto/context/default.hpp</a>></h3></div></div></div> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">context</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Context<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/context/default_eval.html" title="Struct template default_eval">default_eval</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">default_context</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="header.boost.proto.context.null_hpp"></a>Header <<a href="../../../boost/proto/context/null.hpp" target="_top">boost/proto/context/null.hpp</a>></h3></div></div></div> +<p> + Definintion of + <code class="computeroutput"><a class="link" href="../boost/proto/context/null_context.html" title="Struct null_context">proto::context::null_context<></a></code>, + an evaluation context for + <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + that simply evaluates each child expression, doesn't combine the results at all, and returns void. + </p> +<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">context</span> <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <a class="link" href="../Expr.html" title="Concept Expr">Expr</a><span class="special">,</span> <span class="keyword">typename</span> Context<span class="special">></span> <span class="keyword">struct</span> <a class="link" href="../boost/proto/context/null_eval.html" title="Struct template null_eval">null_eval</a><span class="special">;</span> + <span class="keyword">struct</span> <a class="link" href="../boost/proto/context/null_context.html" title="Struct null_context">null_context</a><span class="special">;</span> + <span class="special">}</span> + <span class="special">}</span> +<span class="special">}</span></pre> +</div> +</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 © 2008 Eric Niebler<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="users_guide.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../boost/proto/term.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/proto/users_guide.html b/doc/html/proto/users_guide.html new file mode 100755 index 0000000000..7b19175e92 --- /dev/null +++ b/doc/html/proto/users_guide.html @@ -0,0 +1,10881 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> +<title>Users' Guide</title> +<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> +<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> +<link rel="up" href="../proto.html" title="Chapter 20. Boost.Proto"> +<link rel="prev" href="../proto.html" title="Chapter 20. Boost.Proto"> +<link rel="next" href="reference.html" title="Reference"> +</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.html">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../proto.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +<div class="section"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="proto.users_guide"></a><a class="link" href="users_guide.html" title="Users' Guide">Users' Guide</a> +</h2></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started">Getting Started</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end">Fronts Ends: Defining + Terminals and Non-Terminals of Your EDSL</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form">Intermediate + Form: Understanding and Introspecting Expressions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end">Back Ends: Making Expression + Templates Do Useful Work</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples">Examples</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.resources">Background and Resources</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.glossary">Glossary</a></span></dt> +</dl></div> +<h4> +<a name="proto.users_guide.h0"></a> + <span><a name="proto.users_guide.compilers__compiler_construction_toolkits__and_proto"></a></span><a class="link" href="users_guide.html#proto.users_guide.compilers__compiler_construction_toolkits__and_proto">Compilers, + Compiler Construction Toolkits, and Proto</a> + </h4> +<p> + Most compilers have front ends and back ends. The front end parses the text + of an input program into some intermediate form like an abstract syntax tree, + and the back end takes the intermediate form and generates an executable from + it. + </p> +<p> + A library built with Proto is essentially a compiler for a embedded domain-specific + language (EDSL). It also has a front end, an intermediate form, and a back + end. The front end is comprised of the symbols (a.k.a., terminals), members, + operators and functions that make up the user-visible aspects of the EDSL. + The back end is made of evaluation contexts and transforms that give meaning + and behavior to the expression templates generated by the front end. In between + is the intermediate form: the expression template itself, which is an abstract + syntax tree in a very real sense. + </p> +<p> + To build a library with Proto, you will first decide what your interface will + be; that is, you'll design a programming language for your domain and build + the front end with tools provided by Proto. Then you'll design the back end + by writing evaluation contexts and/or transforms that accept expression templates + and do interesting things with them. + </p> +<p> + This users' guide is organized as follows. After a <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started" title="Getting Started">Getting + Started guide</a>, we'll cover the tools Proto provides for defining and + manipulating the three major parts of a compiler: + </p> +<div class="variablelist"> +<p class="title"><b></b></p> +<dl> +<dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.front_end" title="Fronts Ends: Defining Terminals and Non-Terminals of Your EDSL">Front Ends</a></span></dt> +<dd><p> + How to define the aspects of your EDSL with which your users will interact + directly. + </p></dd> +<dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form" title="Intermediate Form: Understanding and Introspecting Expressions">Intermediate + Form</a></span></dt> +<dd><p> + What Proto expression templates look like, how to discover their structure + and access their constituents. + </p></dd> +<dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.back_end" title="Back Ends: Making Expression Templates Do Useful Work">Back Ends</a></span></dt> +<dd><p> + How to define evaluation contexts and transforms that make expression + templates do interesting things. + </p></dd> +</dl> +</div> +<p> + After that, you may be interested in seeing some <a class="link" href="users_guide.html#boost_proto.users_guide.examples" title="Examples">Examples</a> + to get a better idea of how the pieces all fit together. + </p> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.getting_started"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started" title="Getting Started">Getting Started</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto">Installing + Proto</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.naming">Naming + Conventions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.hello_world">Hello + World</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator">Hello + Calculator</a></span></dt> +</dl></div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.getting_started.installing_proto"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto" title="Installing Proto">Installing + Proto</a> +</h4></div></div></div> +<h6> +<a name="boost_proto.users_guide.getting_started.installing_proto.h0"></a> + <span><a name="boost_proto.users_guide.getting_started.installing_proto.getting_proto"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.getting_proto">Getting + Proto</a> + </h6> +<p> + You can get Proto by downloading Boost (Proto is in version 1.37 and later), + or by accessing Boost's SVN repository on SourceForge.net. Just go to + <a href="http://svn.boost.org/trac/boost/wiki/BoostSubversion" target="_top">http://svn.boost.org/trac/boost/wiki/BoostSubversion</a> + and follow the instructions there for anonymous SVN access. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.installing_proto.h1"></a> + <span><a name="boost_proto.users_guide.getting_started.installing_proto.building_with_proto"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.building_with_proto">Building + with Proto</a> + </h6> +<p> + Proto is a header-only template library, which means you don't need to + alter your build scripts or link to any separate lib file to use it. All + you need to do is <code class="computeroutput"><span class="preprocessor">#include</span> + <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">proto</span><span class="special">/</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>. Or, you might decide to just include + the core of Proto (<code class="computeroutput"><span class="preprocessor">#include</span> + <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">proto</span><span class="special">/</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>) and whichever contexts and transforms + you happen to use. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.installing_proto.h2"></a> + <span><a name="boost_proto.users_guide.getting_started.installing_proto.requirements"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.requirements">Requirements</a> + </h6> +<p> + Proto depends on Boost. You must use either Boost version 1.34.1 or higher, + or the version in SVN trunk. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.installing_proto.h3"></a> + <span><a name="boost_proto.users_guide.getting_started.installing_proto.supported_compilers"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.supported_compilers">Supported + Compilers</a> + </h6> +<p> + Currently, Boost.Proto is known to work on the following compilers: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + Visual C++ 7.1 and higher + </li> +<li class="listitem"> + GNU C++ 3.4 and higher + </li> +<li class="listitem"> + Intel on Linux 8.1 and higher + </li> +<li class="listitem"> + Intel on Windows 9.1 and higher + </li> +</ul></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + Please send any questions, comments and bug reports to eric <at> + boostpro <dot> com. + </p></td></tr> +</table></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.getting_started.naming"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming" title="Naming Conventions">Naming + Conventions</a> +</h4></div></div></div> +<p> + Proto is a large library and probably quite unlike any library you've used + before. Proto uses some consistent naming conventions to make it easier + to navigate, and they're described below. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.naming.h0"></a> + <span><a name="boost_proto.users_guide.getting_started.naming.functions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.functions">Functions</a> + </h6> +<p> + All of Proto's functions are defined in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace. For example, there is a function called <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code> defined in <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + that accepts a terminal expression and returns the terminal's value. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.naming.h1"></a> + <span><a name="boost_proto.users_guide.getting_started.naming.metafunctions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.metafunctions">Metafunctions</a> + </h6> +<p> + Proto defines <span class="emphasis"><em>metafunctions</em></span> that correspond to each + of Proto's free functions. The metafunctions are used to compute the functions' + return types. All of Proto's metafunctions live in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span></code> + namespace and have the same name as the functions to which they correspond. + For instance, there is a class template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><></span></code> that you can use to compute the + return type of the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> function. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.naming.h2"></a> + <span><a name="boost_proto.users_guide.getting_started.naming.function_objects"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.function_objects">Function + Objects</a> + </h6> +<p> + Proto defines <span class="emphasis"><em>function object</em></span> equivalents of all of + its free functions. (A function object is an instance of a class type that + defines an <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + member function.) All of Proto's function object types are defined in the + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span></code> namespace and have the same + name as their corresponding free functions. For example, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span></code> is a class that defines a function + object that does the same thing as the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> free function. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.naming.h3"></a> + <span><a name="boost_proto.users_guide.getting_started.naming.primitive_transforms"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.primitive_transforms">Primitive + Transforms</a> + </h6> +<p> + Proto also defines <span class="emphasis"><em>primitive transforms</em></span> -- class types + that can be used to compose larger transforms for manipulating expression + trees. Many of Proto's free functions have corresponding primitive transforms. + These live in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace and their names have a leading underscore. For instance, the + transform corresponding to the <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code> function is called <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code>. + </p> +<p> + The following table summarizes the discussion above: + </p> +<div class="table"> +<a name="boost_proto.users_guide.getting_started.naming.t0"></a><p class="title"><b>Table 20.1. Proto Naming Conventions</b></p> +<div class="table-contents"><table class="table" summary="Proto Naming Conventions"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Entity + </p> + </th> +<th> + <p> + Example + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + Free Function + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + Metafunction + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + Function Object + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + Transform + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code> + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.getting_started.hello_world"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_world" title="Hello World">Hello + World</a> +</h4></div></div></div> +<p> + Below is a very simple program that uses Proto to build an expression template + and then execute it. + </p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">proto</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">;</span> + +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">};</span> + +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special"><<</span> <span class="string">"hello"</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="string">" world"</span> <span class="special">);</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + This program outputs the following: + </p> +<pre class="programlisting">hello, world +</pre> +<p> + This program builds an object representing the output operation and passes + it to an <code class="computeroutput"><span class="identifier">evaluate</span><span class="special">()</span></code> + function, which then executes it. + </p> +<p> + The basic idea of expression templates is to overload all the operators + so that, rather than evaluating the expression immediately, they build + a tree-like representation of the expression so that it can be evaluated + later. For each operator in an expression, at least one operand must be + Protofied in order for Proto's operator overloads to be found. In the expression + ... + </p> +<pre class="programlisting"><span class="identifier">cout_</span> <span class="special"><<</span> <span class="string">"hello"</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="string">" world"</span> +</pre> +<p> + ... the Protofied sub-expression is <code class="computeroutput"><span class="identifier">cout_</span></code>, + which is the Proto-ification of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>. + The presence of <code class="computeroutput"><span class="identifier">cout_</span></code> "infects" + the expression, and brings Proto's tree-building operator overloads into + consideration. Any literals in the expression are then Protofied by wrapping + them in a Proto terminal before they are combined into larger Proto expressions. + </p> +<p> + Once Proto's operator overloads have built the expression tree, the expression + can be lazily evaluated later by walking the tree. That is what <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code> + does. It is a general tree-walking expression evaluator, whose behavior + is customizable via a <span class="emphasis"><em>context</em></span> parameter. The use of + <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code> + assigns the standard meanings to the operators in the expression. (By using + a different context, you could give the operators in your expressions different + semantics. By default, Proto makes no assumptions about what operators + actually <span class="emphasis"><em>mean</em></span>.) + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_world.h0"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_world.proto_design_philosophy"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_world.proto_design_philosophy">Proto + Design Philosophy</a> + </h6> +<p> + Before we continue, let's use the above example to illustrate an important + design principle of Proto's. The expression template created in the <span class="emphasis"><em>hello + world</em></span> example is totally general and abstract. It is not tied + in any way to any particular domain or application, nor does it have any + particular meaning or behavior on its own, until it is evaluated in a + <span class="emphasis"><em>context</em></span>. Expression templates are really just heterogeneous + trees, which might mean something in one domain, and something else entirely + in a different one. + </p> +<p> + As we'll see later, there is a way to create Proto expression trees that + are <span class="emphasis"><em>not</em></span> purely abstract, and that have meaning and + behaviors independent of any context. There is also a way to control which + operators are overloaded for your particular domain. But that is not the + default behavior. We'll see later why the default is often a good thing. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.getting_started.hello_calculator"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">Hello + Calculator</a> +</h4></div></div></div> +<p> + "Hello, world" is nice, but it doesn't get you very far. Let's + use Proto to build a EDSL (embedded domain-specific language) for a lazily-evaluated + calculator. We'll see how to define the terminals in your mini-language, + how to compose them into larger expressions, and how to define an evaluation + context so that your expressions can do useful work. When we're done, we'll + have a mini-language that will allow us to declare a lazily-evaluated arithmetic + expression, such as <code class="computeroutput"><span class="special">(</span><span class="identifier">_2</span> + <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> + <span class="special">*</span> <span class="number">100</span></code>, + where <code class="computeroutput"><span class="identifier">_1</span></code> and <code class="computeroutput"><span class="identifier">_2</span></code> are placeholders for values to be + passed in when the expression is evaluated. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h0"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.defining_terminals"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.defining_terminals">Defining + Terminals</a> + </h6> +<p> + The first order of business is to define the placeholders <code class="computeroutput"><span class="identifier">_1</span></code> and <code class="computeroutput"><span class="identifier">_2</span></code>. + For that, we'll use the <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal<></a></code> + metafunction. + </p> +<pre class="programlisting"><span class="comment">// Define a placeholder type</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">placeholder</span> +<span class="special">{};</span> + +<span class="comment">// Define the Protofied placeholder terminals</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_2</span> <span class="special">=</span> <span class="special">{{}};</span> +</pre> +<p> + The initialization may look a little odd at first, but there is a good + reason for doing things this way. The objects <code class="computeroutput"><span class="identifier">_1</span></code> + and <code class="computeroutput"><span class="identifier">_2</span></code> above do not require + run-time construction -- they are <span class="emphasis"><em>statically initialized</em></span>, + which means they are essentially initialized at compile time. See the + <a class="link" href="appendices.html#boost_proto.appendices.rationale.static_initialization" title="Static Initialization">Static + Initialization</a> section in the <a class="link" href="appendices.html#boost_proto.appendices.rationale" title="Appendix C: Rationale">Rationale</a> + appendix for more information. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h1"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.constructing_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.constructing_expression_trees">Constructing + Expression Trees</a> + </h6> +<p> + Now that we have terminals, we can use Proto's operator overloads to combine + these terminals into larger expressions. So, for instance, we can immediately + say things like: + </p> +<pre class="programlisting"><span class="comment">// This builds an expression template</span> +<span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">;</span> +</pre> +<p> + This creates an expression tree with a node for each operator. The type + of the resulting object is large and complex, but we are not terribly interested + in it right now. + </p> +<p> + So far, the object is just a tree representing the expression. It has no + behavior. In particular, it is not yet a calculator. Below we'll see how + to make it a calculator by defining an evaluation context. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h2"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.evaluating_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.evaluating_expression_trees">Evaluating + Expression Trees</a> + </h6> +<p> + No doubt you want your expression templates to actually <span class="emphasis"><em>do</em></span> + something. One approach is to define an <span class="emphasis"><em>evaluation context</em></span>. + The context is like a function object that associates behaviors with the + node types in your expression tree. The following example should make it + clear. It is explained below. + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">calculator_context</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// Values to replace the placeholders</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">args</span><span class="special">;</span> + + <span class="comment">// Define the result type of the calculator.</span> + <span class="comment">// (This makes the calculator_context "callable".)</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Handle the placeholders:</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">>)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">args</span><span class="special">[</span><span class="identifier">I</span><span class="special">];</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + In <code class="computeroutput"><span class="identifier">calculator_context</span></code>, + we specify how Proto should evaluate the placeholder terminals by defining + the appropriate overloads of the function call operator. For any other + nodes in the expression tree (e.g., arithmetic operations or non-placeholder + terminals), Proto will evaluate the expression in the "default" + way. For example, a binary plus node is evaluated by first evaluating the + left and right operands and adding the results. Proto's default evaluator + uses the <a href="../../../libs/typeof/index.html" target="_top">Boost.Typeof</a> + library to compute return types. + </p> +<p> + Now that we have an evaluation context for our calculator, we can use it + to evaluate our arithmetic expressions, as below: + </p> +<pre class="programlisting"><span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">45</span><span class="special">);</span> <span class="comment">// the value of _1 is 45</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">50</span><span class="special">);</span> <span class="comment">// the value of _2 is 50</span> + +<span class="comment">// Create an arithmetic expression and immediately evaluate it</span> +<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span> <span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">,</span> <span class="identifier">ctx</span> <span class="special">);</span> + +<span class="comment">// This prints "10"</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">d</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + Later, we'll see how to define more interesting evaluation contexts and + expression transforms that give you total control over how your expressions + are evaluated. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h3"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.customizing_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.customizing_expression_trees">Customizing + Expression Trees</a> + </h6> +<p> + Our calculator EDSL is already pretty useful, and for many EDSL scenarios, + no more would be needed. But let's keep going. Imagine how much nicer it + would be if all calculator expressions overloaded <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> so that they could be used as function + objects. We can do that by creating a calculator <span class="emphasis"><em>domain</em></span> + and telling Proto that all expressions in the calculator domain have extra + members. Here is how to define a calculator domain: + </p> +<pre class="programlisting"><span class="comment">// Forward-declare an expression wrapper</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span><span class="special">;</span> + +<span class="comment">// Define a calculator domain. Expression within</span> +<span class="comment">// the calculator domain will be wrapped in the</span> +<span class="comment">// calculator<> expression wrapper.</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">calculator</span><span class="special">></span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> + type will be an expression wrapper. It will behave just like the expression + that it wraps, but it will have extra member functions that we will define. + The <code class="computeroutput"><span class="identifier">calculator_domain</span></code> is + what informs Proto about our wrapper. It is used below in the definition + of <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code>. + Read on for a description. + </p> +<pre class="programlisting"><span class="comment">// Define a calculator expression wrapper. It behaves just like</span> +<span class="comment">// the expression it wraps, but with an extra operator() member</span> +<span class="comment">// function that evaluates the expression. </span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> + <span class="identifier">base_type</span><span class="special">;</span> + + <span class="identifier">calculator</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Overload operator() to invoke proto::eval() with</span> + <span class="comment">// our calculator_context.</span> + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">a1</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">a2</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">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a1</span><span class="special">);</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a2</span><span class="special">);</span> + + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + The <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> + struct is an expression <span class="emphasis"><em>extension</em></span>. It uses <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><></span></code> + to effectively add additional members to an expression type. When composing + larger expressions from smaller ones, Proto notes what domain the smaller + expressions are in. The larger expression is in the same domain and is + automatically wrapped in the domain's extension wrapper. + </p> +<p> + All that remains to be done is to put our placeholders in the calculator + domain. We do that by wrapping them in our <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> wrapper, as below: + </p> +<pre class="programlisting"><span class="comment">// Define the Protofied placeholder terminals, in the</span> +<span class="comment">// calculator domain.</span> +<span class="identifier">calculator</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_1</span><span class="special">;</span> +<span class="identifier">calculator</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_2</span><span class="special">;</span> +</pre> +<p> + Any larger expression that contain these placeholders will automatically + be wrapped in the <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> wrapper and have our <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + overload. That means we can use them as function objects as follows. + </p> +<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">)(</span><span class="number">45.0</span><span class="special">,</span> <span class="number">50.0</span><span class="special">);</span> +<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="special">(</span><span class="number">50.0</span> <span class="special">-</span> <span class="number">45.0</span><span class="special">)</span> <span class="special">/</span> <span class="number">50.0</span> <span class="special">*</span> <span class="number">100</span><span class="special">));</span> +</pre> +<p> + Since calculator expressions are now valid function objects, we can use + them with standard algorithms, as shown below: + </p> +<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">a1</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">56</span><span class="special">,</span> <span class="number">84</span><span class="special">,</span> <span class="number">37</span><span class="special">,</span> <span class="number">69</span> <span class="special">};</span> +<span class="keyword">double</span> <span class="identifier">a2</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">65</span><span class="special">,</span> <span class="number">120</span><span class="special">,</span> <span class="number">60</span><span class="special">,</span> <span class="number">70</span> <span class="special">};</span> +<span class="keyword">double</span> <span class="identifier">a3</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">0</span> <span class="special">};</span> + +<span class="comment">// Use std::transform() and a calculator expression</span> +<span class="comment">// to calculate percentages given two input sequences:</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">+</span><span class="number">4</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="identifier">a3</span><span class="special">,</span> <span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">);</span> +</pre> +<p> + Now, let's use the calculator example to explore some other useful features + of Proto. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h4"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.detecting_invalid_expressions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.detecting_invalid_expressions">Detecting + Invalid Expressions</a> + </h6> +<p> + You may have noticed that you didn't have to define an overloaded <code class="computeroutput"><span class="keyword">operator</span><span class="special">-()</span></code> + or <code class="computeroutput"><span class="keyword">operator</span><span class="special">/()</span></code> + -- Proto defined them for you. In fact, Proto overloads <span class="emphasis"><em>all</em></span> + the operators for you, even though they may not mean anything in your domain-specific + language. That means it may be possible to create expressions that are + invalid in your domain. You can detect invalid expressions with Proto by + defining the <span class="emphasis"><em>grammar</em></span> of your domain-specific language. + </p> +<p> + For simplicity, assume that our calculator EDSL should only allow addition, + subtraction, multiplication and division. Any expression involving any + other operator is invalid. Using Proto, we can state this requirement by + defining the grammar of the calculator EDSL. It looks as follows: + </p> +<pre class="programlisting"><span class="comment">// Define the grammar of calculator expressions</span> +<span class="keyword">struct</span> <span class="identifier">calculator_grammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + You can read the above grammar as follows: an expression tree conforms + to the calculator grammar if it is a binary plus, minus, multiplies or + divides node, where both child nodes also conform to the calculator grammar; + or if it is a terminal. In a Proto grammar, <code class="computeroutput"><a class="link" href="../boost/proto/_.html" title="Struct _">proto::_</a></code> is a wildcard that matches + any type, so <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span></code> + matches any terminal, whether it is a placeholder or a literal. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + This grammar is actually a little looser than we would like. Only placeholders + and literals that are convertible to doubles are valid terminals. Later + on we'll see how to express things like that in Proto grammars. + </p></td></tr> +</table></div> +<p> + Once you have defined the grammar of your EDSL, you can use the <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a></code> metafunction to check + whether a given expression type conforms to the grammar. For instance, + we might add the following to our <code class="computeroutput"><span class="identifier">calculator</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> overload: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span> <span class="comment">/* ... as before ... */</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">/* ... */</span> + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">a1</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">a2</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="comment">// Check here that the expression we are about to</span> + <span class="comment">// evaluate actually conforms to the calculator grammar.</span> + <span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator_grammar</span><span class="special">>));</span> + <span class="comment">/* ... */</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + The addition of the <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span><span class="special">()</span></code> line enforces at compile time that we + only evaluate expressions that conform to the calculator EDSL's grammar. + With Proto grammars, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><></span></code> and <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span><span class="special">()</span></code> it is very easy to give the users of + your EDSL short and readable compile-time errors when they accidentally + misuse your EDSL. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span><span class="special">()</span></code> + is part of the Boost Metaprogramming Library. To use it, just <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mpl</span><span class="special">/</span><span class="identifier">assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>. + </p></td></tr> +</table></div> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h5"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.controlling_operator_overloads"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.controlling_operator_overloads">Controlling + Operator Overloads</a> + </h6> +<p> + Grammars and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><></span></code> + make it possible to detect when a user has created an invalid expression + and issue a compile-time error. But what if you want to prevent users from + creating invalid expressions in the first place? By using grammars and + domains together, you can disable any of Proto's operator overloads that + would create an invalid expression. It is as simple as specifying the EDSL's + grammar when you define the domain, as shown below: + </p> +<pre class="programlisting"><span class="comment">// Define a calculator domain. Expression within</span> +<span class="comment">// the calculator domain will be wrapped in the</span> +<span class="comment">// calculator<> expression wrapper.</span> +<span class="comment">// NEW: Any operator overloads that would create an</span> +<span class="comment">// expression that does not conform to the</span> +<span class="comment">// calculator grammar is automatically disabled.</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">calculator</span><span class="special">>,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The only thing we changed is we added <code class="computeroutput"><span class="identifier">calculator_grammar</span></code> + as the second template parameter to the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><></span></code> template when defining <code class="computeroutput"><span class="identifier">calculator_domain</span></code>. With this simple addition, + we disable any of Proto's operator overloads that would create an invalid + calculator expression. + </p> +<h6> +<a name="boost_proto.users_guide.getting_started.hello_calculator.h6"></a> + <span><a name="boost_proto.users_guide.getting_started.hello_calculator.____and_much_more"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.____and_much_more">... + And Much More</a> + </h6> +<p> + Hopefully, this gives you an idea of what sorts of things Proto can do + for you. But this only scratches the surface. The rest of this users' guide + will describe all these features and others in more detail. + </p> +<p> + Happy metaprogramming! + </p> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.front_end"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end" title="Fronts Ends: Defining Terminals and Non-Terminals of Your EDSL">Fronts Ends: Defining + Terminals and Non-Terminals of Your EDSL</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.making_terminals">Making + Terminals</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.proto_s_operator_overloads">Proto's + Operator Overloads</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.making_lazy_functions">Making + Lazy Functions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain">Customizing + Expressions in Your Domain</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.define_operators">Adapting + Existing Types to Proto</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.code_repetition">Generating + Repetitive Code with the Preprocessor</a></span></dt> +</dl></div> +<p> + Here is the fun part: designing your own mini-programming language. In this + section we'll talk about the nuts and bolts of designing a EDSL interface + using Proto. We'll cover the definition of terminals and lazy functions that + the users of your EDSL will get to program with. We'll also talk about Proto's + expression template-building operator overloads, and about ways to add additional + members to expressions within your domain. + </p> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.front_end.making_terminals"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.making_terminals" title="Making Terminals">Making + Terminals</a> +</h4></div></div></div> +<p> + As we saw with the Calculator example from the Introduction, the simplest + way to get a EDSL up and running is simply to define some terminals, as + follows. + </p> +<pre class="programlisting"><span class="comment">// Define a literal integer Proto expression.</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">{</span><span class="number">0</span><span class="special">};</span> + +<span class="comment">// This creates an expression template.</span> +<span class="identifier">i</span> <span class="special">+</span> <span class="number">1</span><span class="special">;</span> +</pre> +<p> + With some terminals and Proto's operator overloads, you can immediately + start creating expression templates. + </p> +<p> + Defining terminals -- with aggregate initialization -- can be a little + awkward at times. Proto provides an easier-to-use wrapper for literals + that can be used to construct Protofied terminal expressions. It's called + <code class="computeroutput"><a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal<></a></code>. + </p> +<pre class="programlisting"><span class="comment">// Define a literal integer Proto expression.</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> + +<span class="comment">// Proto literals are really just Proto terminal expressions.</span> +<span class="comment">// For example, this builds a Proto expression template:</span> +<span class="identifier">i</span> <span class="special">+</span> <span class="number">1</span><span class="special">;</span> +</pre> +<p> + There is also a <code class="computeroutput"><a class="link" href="../boost/proto/lit.html" title="Function lit">proto::lit()</a></code> function for constructing + a <code class="computeroutput"><a class="link" href="../boost/proto/literal.html" title="Struct template literal">proto::literal<></a></code> in-place. The above + expression can simply be written as: + </p> +<pre class="programlisting"><span class="comment">// proto::lit(0) creates an integer terminal expression</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">+</span> <span class="number">1</span><span class="special">;</span> +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.front_end.proto_s_operator_overloads"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.proto_s_operator_overloads" title="Proto's Operator Overloads">Proto's + Operator Overloads</a> +</h4></div></div></div> +<p> + Once we have some Proto terminals, expressions involving those terminals + build expression trees for us. Proto defines overloads for each of C++'s + overloadable operators in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace. As long as one operand is a Proto expression, the result of + the operation is a tree node representing that operation. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + Proto's operator overloads live in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace and are found via ADL (argument-dependent lookup). That is + why expressions must be "tainted" with Proto-ness for Proto + to be able to build trees out of expressions. + </p></td></tr> +</table></div> +<p> + As a result of Proto's operator overloads, we can say: + </p> +<pre class="programlisting"><span class="special">-</span><span class="identifier">_1</span><span class="special">;</span> <span class="comment">// OK, build a unary-negate tree node</span> +<span class="identifier">_1</span> <span class="special">+</span> <span class="number">42</span><span class="special">;</span> <span class="comment">// OK, build a binary-plus tree node</span> +</pre> +<p> + For the most part, this Just Works and you don't need to think about it, + but a few operators are special and it can be helpful to know how Proto + handles them. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.proto_s_operator_overloads.h0"></a> + <span><a name="boost_proto.users_guide.front_end.proto_s_operator_overloads.assignment__subscript__and_function_call_operators"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.proto_s_operator_overloads.assignment__subscript__and_function_call_operators">Assignment, + Subscript, and Function Call Operators</a> + </h6> +<p> + Proto also overloads <code class="computeroutput"><span class="keyword">operator</span><span class="special">=</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>, and <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>, but these operators are member functions + of the expression template rather than free functions in Proto's namespace. + The following are valid Proto expressions: + </p> +<pre class="programlisting"><span class="identifier">_1</span> <span class="special">=</span> <span class="number">5</span><span class="special">;</span> <span class="comment">// OK, builds a binary assign tree node</span> +<span class="identifier">_1</span><span class="special">[</span><span class="number">6</span><span class="special">];</span> <span class="comment">// OK, builds a binary subscript tree node</span> +<span class="identifier">_1</span><span class="special">();</span> <span class="comment">// OK, builds a unary function tree node</span> +<span class="identifier">_1</span><span class="special">(</span><span class="number">7</span><span class="special">);</span> <span class="comment">// OK, builds a binary function tree node</span> +<span class="identifier">_1</span><span class="special">(</span><span class="number">8</span><span class="special">,</span><span class="number">9</span><span class="special">);</span> <span class="comment">// OK, builds a ternary function tree node</span> +<span class="comment">// ... etc.</span> +</pre> +<p> + For the first two lines, assignment and subscript, it should be fairly + unsurprising that the resulting expression node should be binary. After + all, there are two operands in each expression. It may be surprising at + first that what appears to be a function call with no arguments, <code class="computeroutput"><span class="identifier">_1</span><span class="special">()</span></code>, + actually creates an expression node with one child. The child is <code class="computeroutput"><span class="identifier">_1</span></code> itself. Likewise, the expression + <code class="computeroutput"><span class="identifier">_1</span><span class="special">(</span><span class="number">7</span><span class="special">)</span></code> has two + children: <code class="computeroutput"><span class="identifier">_1</span></code> and <code class="computeroutput"><span class="number">7</span></code>. + </p> +<p> + Because these operators can only be defined as member functions, the following + expressions are invalid: + </p> +<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> +<span class="identifier">i</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">;</span> <span class="comment">// ERROR: cannot assign _1 to an int</span> + +<span class="keyword">int</span> <span class="special">*</span><span class="identifier">p</span><span class="special">;</span> +<span class="identifier">p</span><span class="special">[</span><span class="identifier">_1</span><span class="special">];</span> <span class="comment">// ERROR: cannot use _1 as an index</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">sin</span><span class="special">(</span><span class="identifier">_1</span><span class="special">);</span> <span class="comment">// ERROR: cannot call std::sin() with _1</span> +</pre> +<p> + Also, C++ has special rules for overloads of <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code> that make it useless for building + expression templates, so Proto does not overload it. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.proto_s_operator_overloads.h1"></a> + <span><a name="boost_proto.users_guide.front_end.proto_s_operator_overloads.the_address_of_operator"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.proto_s_operator_overloads.the_address_of_operator">The + Address-Of Operator</a> + </h6> +<p> + Proto overloads the address-of operator for expression types, so that the + following code creates a new unary address-of tree node: + </p> +<pre class="programlisting"><span class="special">&</span><span class="identifier">_1</span><span class="special">;</span> <span class="comment">// OK, creates a unary address-of tree node</span> +</pre> +<p> + It does <span class="emphasis"><em>not</em></span> return the address of the <code class="computeroutput"><span class="identifier">_1</span></code> object. However, there is special + code in Proto such that a unary address-of node is implicitly convertible + to a pointer to its child. In other words, the following code works and + does what you might expect, but not in the obvious way: + </p> +<pre class="programlisting"><span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">_1_type</span><span class="special">;</span> + +<span class="identifier">_1_type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> +<span class="identifier">_1_type</span> <span class="keyword">const</span> <span class="special">*</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">_1</span><span class="special">;</span> <span class="comment">// OK, &_1 implicitly converted</span> +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.front_end.making_lazy_functions"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.making_lazy_functions" title="Making Lazy Functions">Making + Lazy Functions</a> +</h4></div></div></div> +<p> + If we limited ourselves to nothing but terminals and operator overloads, + our embedded domain-specific languages wouldn't be very expressive. Imagine + that we wanted to extend our calculator EDSL with a full suite of math + functions like <code class="computeroutput"><span class="identifier">sin</span><span class="special">()</span></code> + and <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> + that we could invoke lazily as follows. + </p> +<pre class="programlisting"><span class="comment">// A calculator expression that takes one argument</span> +<span class="comment">// and takes the sine of it.</span> +<span class="identifier">sin</span><span class="special">(</span><span class="identifier">_1</span><span class="special">);</span> +</pre> +<p> + We would like the above to create an expression template representing a + function invocation. When that expression is evaluated, it should cause + the function to be invoked. (At least, that's the meaning of function invocation + we'd like the calculator EDSL to have.) You can define <code class="computeroutput"><span class="identifier">sin</span></code> + quite simply as follows. + </p> +<pre class="programlisting"><span class="comment">// "sin" is a Proto terminal containing a function pointer</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">double</span><span class="special">(*)(</span><span class="keyword">double</span><span class="special">)</span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">sin</span> <span class="special">=</span> <span class="special">{&</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">sin</span><span class="special">};</span> +</pre> +<p> + In the above, we define <code class="computeroutput"><span class="identifier">sin</span></code> + as a Proto terminal containing a pointer to the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sin</span><span class="special">()</span></code> function. Now we can use <code class="computeroutput"><span class="identifier">sin</span></code> as a lazy function. The <code class="computeroutput"><span class="identifier">default_context</span></code> that we saw in the Introduction + knows how to evaluate lazy functions. Consider the following: + </p> +<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">pi</span> <span class="special">=</span> <span class="number">3.1415926535</span><span class="special">;</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_context</span> <span class="identifier">ctx</span><span class="special">;</span> +<span class="comment">// Create a lazy "sin" invocation and immediately evaluate it</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">pi</span><span class="special">/</span><span class="number">2</span><span class="special">),</span> <span class="identifier">ctx</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + The above code prints out: + </p> +<pre class="programlisting">1</pre> +<p> + It is important to note that there is nothing special about terminals that + contain function pointers. <span class="emphasis"><em>Any</em></span> Proto expression has + an overloaded function call operator. Consider: + </p> +<pre class="programlisting"><span class="comment">// This compiles!</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">1</span><span class="special">)(</span><span class="number">2</span><span class="special">)(</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">)(</span><span class="number">5</span><span class="special">,</span><span class="number">6</span><span class="special">,</span><span class="number">7</span><span class="special">,</span><span class="number">8</span><span class="special">);</span> +</pre> +<p> + That may look strange at first. It creates an integer terminal with <code class="computeroutput"><a class="link" href="../boost/proto/lit.html" title="Function lit">proto::lit()</a></code>, and then invokes it like + a function again and again. What does it mean? To be sure, the <code class="computeroutput"><span class="identifier">default_context</span></code> wouldn't know what to + do with it. The <code class="computeroutput"><span class="identifier">default_context</span></code> + only knows how to evaluate expressions that are sufficiently C++-like. + In the case of function call expressions, the left hand side must evaluate + to something that can be invoked: a pointer to a function, a reference + to a function, or a TR1-style function object. That doesn't stop you from + defining your own evaluation context that gives that expression a meaning. + But more on that later. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.making_lazy_functions.h0"></a> + <span><a name="boost_proto.users_guide.front_end.making_lazy_functions.making_lazy_functions__continued"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.making_lazy_functions.making_lazy_functions__continued">Making + Lazy Functions, Continued</a> + </h6> +<p> + Now, what if we wanted to add a <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> function to our calculator EDSL that + users could invoke as follows? + </p> +<pre class="programlisting"><span class="comment">// A calculator expression that takes one argument</span> +<span class="comment">// and raises it to the 2nd power</span> +<span class="identifier">pow</span><span class="special"><</span> <span class="number">2</span> <span class="special">>(</span><span class="identifier">_1</span><span class="special">);</span> +</pre> +<p> + The simple technique described above of making <code class="computeroutput"><span class="identifier">pow</span></code> + a terminal containing a function pointer doesn't work here. If <code class="computeroutput"><span class="identifier">pow</span></code> is an object, then the expression + <code class="computeroutput"><span class="identifier">pow</span><span class="special"><</span> + <span class="number">2</span> <span class="special">>(</span><span class="identifier">_1</span><span class="special">)</span></code> is + not valid C++. <code class="computeroutput"><span class="identifier">pow</span></code> needs + to be a real function template. But it must be an unusual function; it + must return an expression template. + </p> +<p> + Before we can write the <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> function, we need a function object that + wraps an invocation of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pow</span><span class="special">()</span></code>. + </p> +<pre class="programlisting"><span class="comment">// Define a pow_fun function object</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Exp</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">pow_fun</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">d</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pow</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span> <span class="identifier">Exp</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + Now, let's try to define a function template that returns an expression + template. We'll use the <code class="computeroutput"><a class="link" href="../boost/proto/function.html" title="Struct template function">proto::function<></a></code> + metafunction to calculate the type of a Proto expression that represents + a function call. It is analogous to <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal<></a></code>. + (We'll see a couple of different ways to solve this problem, and each will + demonstrate another utility for defining Proto front-ends.) + </p> +<pre class="programlisting"><span class="comment">// Define a lazy pow() function for the calculator EDSL.</span> +<span class="comment">// Can be used as: pow< 2 >(_1)</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Exp</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> +<span class="identifier">pow</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">arg</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">{{{}},</span> <span class="identifier">arg</span><span class="special">};</span> + <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + In the code above, notice how the <code class="computeroutput"><a class="link" href="../boost/proto/function.html" title="Struct template function">proto::function<></a></code> + and <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal<></a></code> metafunctions are used + to calculate the return type: <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> returns an expression template representing + a function call where the first child is the function to call and the second + is the argument to the function. (Unfortunately, the same type calculation + is repeated in the body of the function so that we can initialize a local + variable of the correct type. We'll see in a moment how to avoid that.) + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + As with <code class="computeroutput"><a class="link" href="../boost/proto/function.html" title="Struct template function">proto::function<></a></code>, there are metafunctions + corresponding to all of the overloadable C++ operators for calculating + expression types. + </p></td></tr> +</table></div> +<p> + With the above definition of the <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> function, we can create calculator expressions + like the one below and evaluate them using the <code class="computeroutput"><span class="identifier">calculator_context</span></code> + we implemented in the Introduction. + </p> +<pre class="programlisting"><span class="comment">// Initialize a calculator context</span> +<span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">3</span><span class="special">);</span> <span class="comment">// let _1 be 3</span> + +<span class="comment">// Create a calculator expression that takes one argument,</span> +<span class="comment">// adds one to it, and raises it to the 2nd power; and then</span> +<span class="comment">// immediately evaluate it using the calculator_context.</span> +<span class="identifier">assert</span><span class="special">(</span> <span class="number">16</span> <span class="special">==</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span> <span class="identifier">pow</span><span class="special"><</span><span class="number">2</span><span class="special">>(</span> <span class="identifier">_1</span> <span class="special">+</span> <span class="number">1</span> <span class="special">),</span> <span class="identifier">ctx</span> <span class="special">)</span> <span class="special">);</span> +</pre> +<h6> +<a name="boost_proto.users_guide.front_end.making_lazy_functions.h1"></a> + <span><a name="boost_proto.users_guide.front_end.making_lazy_functions.protofying_lazy_function_arguments"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.making_lazy_functions.protofying_lazy_function_arguments">Protofying + Lazy Function Arguments</a> + </h6> +<p> + Above, we defined a <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> function template that returns an expression + template representing a lazy function invocation. But if we tried to call + it as below, we'll run into a problem. + </p> +<pre class="programlisting"><span class="comment">// ERROR: pow() as defined above doesn't work when</span> +<span class="comment">// called with a non-Proto argument.</span> +<span class="identifier">pow</span><span class="special"><</span> <span class="number">2</span> <span class="special">>(</span> <span class="number">4</span> <span class="special">);</span> +</pre> +<p> + Proto expressions can only have other Proto expressions as children. But + if we look at <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code>'s + function signature, we can see that if we pass it a non-Proto object, it + will try to make it a child. + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Exp</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> <span class="comment">// <=== ERROR! This may not be a Proto type!</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> +<span class="identifier">pow</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">arg</span><span class="special">)</span> +</pre> +<p> + What we want is a way to make <code class="computeroutput"><span class="identifier">Arg</span></code> + into a Proto terminal if it is not a Proto expression already, and leave + it alone if it is. For that, we can use <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code>. + The following implementation of the <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> function handles all argument types, + expression templates or otherwise. + </p> +<pre class="programlisting"><span class="comment">// Define a lazy pow() function for the calculator EDSL. Use</span> +<span class="comment">// proto::as_child() to Protofy the argument, but only if it</span> +<span class="comment">// is not a Proto expression type to begin with!</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Exp</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">as_child</span><span class="special"><</span><span class="identifier">Arg</span> <span class="keyword">const</span><span class="special">>::</span><span class="identifier">type</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> +<span class="identifier">pow</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">arg</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">as_child</span><span class="special"><</span><span class="identifier">Arg</span> <span class="keyword">const</span><span class="special">>::</span><span class="identifier">type</span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">{{{}},</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_child</span><span class="special">(</span><span class="identifier">arg</span><span class="special">)};</span> + <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + Notice how we use the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">as_child</span><span class="special"><></span></code> metafunction to calculate the return + type, and the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_child</span><span class="special">()</span></code> + function to actually normalize the argument. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.making_lazy_functions.h2"></a> + <span><a name="boost_proto.users_guide.front_end.making_lazy_functions.lazy_functions_made_simple_with__literal_make_expr____literal_"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.making_lazy_functions.lazy_functions_made_simple_with__literal_make_expr____literal_">Lazy + Functions Made Simple With <code class="literal">make_expr()</code></a> + </h6> +<p> + The versions of the <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> function we've seen above are rather + verbose. In the return type calculation, you have to be very explicit about + wrapping non-Proto types. Worse, you have to restate the return type calculation + in the body of <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> + itself. Proto provides a helper for building expression templates directly + that handles these mundane details for you. It's called <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code>. + We can redefine <code class="computeroutput"><span class="identifier">pow</span><span class="special">()</span></code> + with it as below. + </p> +<pre class="programlisting"><span class="comment">// Define a lazy pow() function for the calculator EDSL.</span> +<span class="comment">// Can be used as: pow< 2 >(_1)</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Exp</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span> <span class="comment">// Tag type</span> + <span class="special">,</span> <span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span> <span class="comment">// First child (by value)</span> + <span class="special">,</span> <span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span> <span class="comment">// Second child (by reference)</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> +<span class="identifier">pow</span><span class="special">(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">arg</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span><span class="special">>(</span> + <span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">>()</span> <span class="comment">// First child (by value)</span> + <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">arg</span><span class="special">)</span> <span class="comment">// Second child (by reference)</span> + <span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + There are some things to notice about the above code. We use <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><></span></code> + to calculate the return type. The first template parameter is the tag type + for the expression node we're building -- in this case, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span></code>, + which is the tag type Proto uses for function call expressions. + </p> +<p> + Subsequent template parameters to <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><></span></code> represent children nodes. If a + child type is not already a Proto expression, it is made into a terminal + with <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code>. A type such as <code class="computeroutput"><span class="identifier">pow_fun</span><span class="special"><</span><span class="identifier">Exp</span><span class="special">></span></code> + results in terminal that is held by value, whereas a type like <code class="computeroutput"><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span></code> (note the reference) indicates that + the result should be held by reference. + </p> +<p> + In the function body is the runtime invocation of <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code>. + It closely mirrors the return type calculation. <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code> + requires you to specify the node's tag type as a template parameter. The + arguments to the function become the node's children. When a child should + be stored by value, nothing special needs to be done. When a child should + be stored by reference, you must use the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">()</span></code> function to wrap the argument. Without + this extra information, the <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code> + function couldn't know whether to store a child by value or by reference. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain" title="Customizing Expressions in Your Domain">Customizing + Expressions in Your Domain</a> +</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.domains">Domains</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends">The + <code class="literal">extends<></code> Expression Wrapper</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.expression_generators">Expression + Generators</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.inhibiting_overloads">Controlling + Operator Overloads</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child">Controlling + How Child Expressions Are Captured</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains">EDSL + Interoperatability: Sub-Domains</a></span></dt> +</dl></div> +<p> + In this section, we'll learn all about <span class="emphasis"><em>domains</em></span>. In + particular, we'll learn: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + How to associate Proto expressions with a domain, + </li> +<li class="listitem"> + How to add members to expressions within a domain, + </li> +<li class="listitem"> + How to use a <span class="emphasis"><em>generator</em></span> to post-process all new + expressions created in your domain, + </li> +<li class="listitem"> + How to control which operators are overloaded in a domain, + </li> +<li class="listitem"> + How to specify capturing policies for child expressions and non-Proto + objects, and + </li> +<li class="listitem"> + How to make expressions from separate domains interoperate. + </li> +</ul></div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.domains"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.domains" title="Domains">Domains</a> +</h5></div></div></div> +<p> + In the <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">Hello + Calculator</a> section, we looked into making calculator expressions + directly usable as lambda expressions in calls to STL algorithms, as + below: + </p> +<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">data</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">1.</span><span class="special">,</span> <span class="number">2.</span><span class="special">,</span> <span class="number">3.</span><span class="special">,</span> <span class="number">4.</span><span class="special">};</span> + +<span class="comment">// Use the calculator EDSL to square each element ... HOW?</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">data</span> <span class="special">+</span> <span class="number">4</span><span class="special">,</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">_1</span> <span class="special">*</span> <span class="identifier">_1</span> <span class="special">);</span> +</pre> +<p> + The difficulty, if you recall, was that by default Proto expressions + don't have interesting behaviors of their own. They're just trees. In + particular, the expression <code class="computeroutput"><span class="identifier">_1</span> + <span class="special">*</span> <span class="identifier">_1</span></code> + won't have an <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + that takes a double and returns a double like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">()</span></code> expects -- unless we give it one. To + make this work, we needed to define an expression wrapper type that defined + the <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + member function, and we needed to associate the wrapper with the calculator + <span class="emphasis"><em>domain</em></span>. + </p> +<p> + In Proto, the term <span class="emphasis"><em>domain</em></span> refers to a type that + associates expressions in that domain to an expression <span class="emphasis"><em>generator</em></span>. + The generator is just a function object that accepts an expression and + does something to it, like wrapping it in an expression wrapper. + </p> +<p> + You can also use a domain to associate expressions with a grammar. When + you specify a domain's grammar, Proto ensures that all the expressions + it generates in that domain conform to the domain's grammar. It does + that by disabling any operator overloads that would create invalid expressions. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends" title="The extends<> Expression Wrapper">The + <code class="literal">extends<></code> Expression Wrapper</a> +</h5></div></div></div> +<p> + The first step to giving your calculator expressions extra behaviors + is to define a calculator domain. All expressions within the calculator + domain will be imbued with calculator-ness, as we'll see. + </p> +<pre class="programlisting"><span class="comment">// A type to be used as a domain tag (to be defined below)</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span><span class="special">;</span> +</pre> +<p> + We use this domain type when extending the <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> + type, which we do with the <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + class template. Here is our expression wrapper, which imbues an expression + with calculator-ness. It is described below. + </p> +<pre class="programlisting"><span class="comment">// The calculator<> expression wrapper makes expressions</span> +<span class="comment">// function objects.</span> +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">>,</span> <span class="identifier">calculator_domain</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span> <span class="identifier">Expr</span> <span class="special">>,</span> <span class="identifier">calculator_domain</span> <span class="special">></span> + <span class="identifier">base_type</span><span class="special">;</span> + + <span class="identifier">calculator</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">()</span> <span class="special">)</span> + <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span> <span class="identifier">expr</span> <span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// This is usually needed because by default, the compiler-</span> + <span class="comment">// generated assignment operator hides extends<>::operator=</span> + <span class="identifier">BOOST_PROTO_EXTENDS_USING_ASSIGN</span><span class="special">(</span><span class="identifier">calculator</span><span class="special">)</span> + + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Hide base_type::operator() by defining our own which</span> + <span class="comment">// evaluates the calculator expression with a calculator context.</span> + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.0</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="comment">// As defined in the Hello Calculator section.</span> + <span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> + + <span class="comment">// ctx.args is a vector<double> that holds the values</span> + <span class="comment">// with which we replace the placeholders (e.g., _1 and _2)</span> + <span class="comment">// in the expression.</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">d1</span> <span class="special">);</span> <span class="comment">// _1 gets the value of d1</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">d2</span> <span class="special">);</span> <span class="comment">// _2 gets the value of d2</span> + + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span> <span class="special">);</span> <span class="comment">// evaluate the expression</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + We want calculator expressions to be function objects, so we have to + define an <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + that takes and returns doubles. The <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> wrapper above does that with + the help of the <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + template. The first template to <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + parameter is the expression type we are extending. The second is the + type of the wrapped expression. The third parameter is the domain that + this wrapper is associated with. A wrapper type like <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> that inherits from <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> behaves just like + the expression type it has extended, with any additional behaviors you + choose to give it. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>Why not just inherit from <code class="literal">proto::expr<></code>?</strong></span> + </p> +<p> + You might be thinking that this expression extension business is unnecessarily + complicated. After all, isn't this why C++ supports inheritance? Why + can't <code class="literal">calculator<Expr></code> just inherit from + <code class="literal">Expr</code> directly? The reason is because <code class="literal">Expr</code>, + which presumably is an instantiation of <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code>, + has expression template-building operator overloads that will be incorrect + for derived types. They will store <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by reference to <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><></span></code>, effectively slicing off any + derived parts. <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + gives your derived types operator overloads that don't slice off your + additional members. + </p> +</td></tr> +</table></div> +<p> + Although not strictly necessary in this case, we bring <code class="computeroutput"><span class="identifier">extends</span><span class="special"><>::</span><span class="keyword">operator</span><span class="special">=</span></code> + into scope with the <code class="computeroutput"><span class="identifier">BOOST_PROTO_EXTENDS_USING_ASSIGN</span><span class="special">()</span></code> macro. This is really only necessary + if you want expressions like <code class="computeroutput"><span class="identifier">_1</span> + <span class="special">=</span> <span class="number">3</span></code> + to create a lazily evaluated assignment. <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + defines the appropriate <code class="computeroutput"><span class="keyword">operator</span><span class="special">=</span></code> for you, but the compiler-generated + <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><>::</span><span class="keyword">operator</span><span class="special">=</span></code> + will hide it unless you make it available with the macro. + </p> +<p> + Note that in the implementation of <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><>::</span><span class="keyword">operator</span><span class="special">()</span></code>, we evaluate the expression with the + <code class="computeroutput"><span class="identifier">calculator_context</span></code> we + defined earlier. As we saw before, the context is what gives the operators + their meaning. In the case of the calculator, the context is also what + defines the meaning of the placeholder terminals. + </p> +<p> + Now that we have defined the <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> expression wrapper, we need to + wrap the placeholders to imbue them with calculator-ness: + </p> +<pre class="programlisting"><span class="identifier">calculator</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> <span class="keyword">const</span> <span class="identifier">_1</span><span class="special">;</span> +<span class="identifier">calculator</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> <span class="keyword">const</span> <span class="identifier">_2</span><span class="special">;</span> +</pre> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends.h0"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends.retaining_pod_ness_with__literal_boost_proto_extends____literal_"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends.retaining_pod_ness_with__literal_boost_proto_extends____literal_">Retaining + POD-ness with <code class="literal">BOOST_PROTO_EXTENDS()</code></a> + </h6> +<p> + To use <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code>, your extension type + must derive from <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code>. + Unfortunately, that means that your extension type is no longer POD and + its instances cannot be <span class="emphasis"><em>statically initialized</em></span>. + (See the <a class="link" href="appendices.html#boost_proto.appendices.rationale.static_initialization" title="Static Initialization">Static + Initialization</a> section in the <a class="link" href="appendices.html#boost_proto.appendices.rationale" title="Appendix C: Rationale">Rationale</a> + appendix for why this matters.) In particular, as defined above, the + global placeholder objects <code class="computeroutput"><span class="identifier">_1</span></code> + and <code class="computeroutput"><span class="identifier">_2</span></code> will need to be + initialized at runtime, which could lead to subtle order of initialization + bugs. + </p> +<p> + There is another way to make an expression extension that doesn't sacrifice + POD-ness : the <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code> + macro. You can use it much like you use <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code>. + We can use <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code> + to keep <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> + a POD and our placeholders statically initialized. + </p> +<pre class="programlisting"><span class="comment">// The calculator<> expression wrapper makes expressions</span> +<span class="comment">// function objects.</span> +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span> +<span class="special">{</span> + <span class="comment">// Use BOOST_PROTO_EXTENDS() instead of proto::extends<> to</span> + <span class="comment">// make this type a Proto expression extension.</span> + <span class="identifier">BOOST_PROTO_EXTENDS</span><span class="special">(</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">)</span> + + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.0</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="comment">/* ... as before ... */</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + With the new <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> type, we can redefine our placeholders + to be statically initialized: + </p> +<pre class="programlisting"><span class="identifier">calculator</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{{}}};</span> +<span class="identifier">calculator</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> <span class="keyword">const</span> <span class="identifier">_2</span> <span class="special">=</span> <span class="special">{{{}}};</span> +</pre> +<p> + We need to make one additional small change to accommodate the POD-ness + of our expression extension, which we'll describe below in the section + on expression generators. + </p> +<p> + What does <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code> + do? It defines a data member of the expression type being extended; some + nested typedefs that Proto requires; <code class="computeroutput"><span class="keyword">operator</span><span class="special">=</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code> and <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> overloads for building expression templates; + and a nested <code class="computeroutput"><span class="identifier">result</span><span class="special"><></span></code> + template for calculating the return type of <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>. In this case, however, the <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + overloads and the <code class="computeroutput"><span class="identifier">result</span><span class="special"><></span></code> template are not needed because + we are defining our own <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> in the <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> type. Proto provides additional + macros for finer control over which member functions are defined. We + could improve our <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> type as follows: + </p> +<pre class="programlisting"><span class="comment">// The calculator<> expression wrapper makes expressions</span> +<span class="comment">// function objects.</span> +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span> +<span class="special">{</span> + <span class="comment">// Use BOOST_PROTO_BASIC_EXTENDS() instead of proto::extends<> to</span> + <span class="comment">// make this type a Proto expression extension:</span> + <span class="identifier">BOOST_PROTO_BASIC_EXTENDS</span><span class="special">(</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">)</span> + + <span class="comment">// Define operator[] to build expression templates:</span> + <span class="identifier">BOOST_PROTO_EXTENDS_SUBSCRIPT</span><span class="special">()</span> + + <span class="comment">// Define operator= to build expression templates:</span> + <span class="identifier">BOOST_PROTO_EXTENDS_ASSIGN</span><span class="special">()</span> + + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.0</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="comment">/* ... as before ... */</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + Notice that we are now using <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a></code>()</code> + instead of <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code>. + This just adds the data member and the nested typedefs but not any of + the overloaded operators. Those are added separately with <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_ASSIGN">BOOST_PROTO_EXTENDS_ASSIGN</a></code>()</code> + and <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_SUBSCRIPT.html" title="Macro BOOST_PROTO_EXTENDS_SUBSCRIPT">BOOST_PROTO_EXTENDS_SUBSCRIPT</a></code>()</code>. + We are leaving out the function call operator and the nested <code class="computeroutput"><span class="identifier">result</span><span class="special"><></span></code> + template that could have been defined with Proto's <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_FUNCTION.html" title="Macro BOOST_PROTO_EXTENDS_FUNCTION">BOOST_PROTO_EXTENDS_FUNCTION</a></code>()</code> + macro. + </p> +<p> + In summary, here are the macros you can use to define expression extensions, + and a brief description of each. + </p> +<div class="table"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.extends.t0"></a><p class="title"><b>Table 20.2. Expression Extension Macros</b></p> +<div class="table-contents"><table class="table" summary="Expression Extension Macros"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Macro + </p> + </th> +<th> + <p> + Purpose + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> +</p> +<pre class="programlisting"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a></code><span class="special">(</span> + <em class="replaceable"><code>expression</code></em> + <span class="special">,</span> <em class="replaceable"><code>extension</code></em> + <span class="special">,</span> <em class="replaceable"><code>domain</code></em> +<span class="special">)</span></pre> +<p> + </p> + </td> +<td> + <p> + Defines a data member of type <code class="computeroutput"><em class="replaceable"><code>expression</code></em></code> + and some nested typedefs that Proto requires. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_ASSIGN">BOOST_PROTO_EXTENDS_ASSIGN</a></code>()</code> + </p> + </td> +<td> + <p> + Defines <code class="computeroutput"><span class="keyword">operator</span><span class="special">=</span></code>. Only valid when preceded + by <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a></code>()</code>. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_SUBSCRIPT.html" title="Macro BOOST_PROTO_EXTENDS_SUBSCRIPT">BOOST_PROTO_EXTENDS_SUBSCRIPT</a></code>()</code> + </p> + </td> +<td> + <p> + Defines <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>. Only valid when preceded + by <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a></code>()</code>. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_FUNCTION.html" title="Macro BOOST_PROTO_EXTENDS_FUNCTION">BOOST_PROTO_EXTENDS_FUNCTION</a></code>()</code> + </p> + </td> +<td> + <p> + Defines <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> and a nested <code class="computeroutput"><span class="identifier">result</span><span class="special"><></span></code> + template for return type calculation. Only valid when preceded + by <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a></code>()</code>. + </p> + </td> +</tr> +<tr> +<td> + <p> +</p> +<pre class="programlisting"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code><span class="special">(</span> + <em class="replaceable"><code>expression</code></em> + <span class="special">,</span> <em class="replaceable"><code>extension</code></em> + <span class="special">,</span> <em class="replaceable"><code>domain</code></em> +<span class="special">)</span></pre> +<p> + </p> + </td> +<td> + <p> + Equivalent to: +</p> +<pre class="programlisting"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_BASIC_EXTENDS.html" title="Macro BOOST_PROTO_BASIC_EXTENDS">BOOST_PROTO_BASIC_EXTENDS</a></code><span class="special">(</span><em class="replaceable"><code>expression</code></em><span class="special">,</span> <em class="replaceable"><code>extension</code></em><span class="special">,</span> <em class="replaceable"><code>domain</code></em><span class="special">)</span> + + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_ASSIGN.html" title="Macro BOOST_PROTO_EXTENDS_ASSIGN">BOOST_PROTO_EXTENDS_ASSIGN</a></code>()</code> + + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_SUBSCRIPT.html" title="Macro BOOST_PROTO_EXTENDS_SUBSCRIPT">BOOST_PROTO_EXTENDS_SUBSCRIPT</a></code>()</code> + + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS_FUNCTION.html" title="Macro BOOST_PROTO_EXTENDS_FUNCTION">BOOST_PROTO_EXTENDS_FUNCTION</a></code>()</code></pre> +<p> + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><div class="warning"><table border="0" summary="Warning"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../doc/src/images/warning.png"></td> +<th align="left">Warning</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>Argument-Dependent Lookup and <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code></strong></span> + </p> +<p> + Proto's operator overloads are defined in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace and are found by argument-dependent lookup (ADL). This usually + just works because expressions are made up of types that live in the + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> namespace. However, sometimes + when you use <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code> + that is not the case. Consider: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_complex</span> +<span class="special">{</span> + <span class="identifier">BOOST_PROTO_EXTENDS</span><span class="special">(</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="identifier">my_complex</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span> + <span class="special">)</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">my_complex</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">c0</span><span class="special">,</span> <span class="identifier">c1</span><span class="special">;</span> + + <span class="identifier">c0</span> <span class="special">+</span> <span class="identifier">c1</span><span class="special">;</span> <span class="comment">// ERROR: operator+ not found</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The problem has to do with how argument-dependent lookup works. The + type <code class="computeroutput"><span class="identifier">my_complex</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> + is not associated in any way with the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace, so the operators defined there are not considered. (Had + we inherited from <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + instead of used <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code>, + we would have avoided the problem because inheriting from a type in + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> namespace is enough to get + ADL to kick in.) + </p> +<p> + So what can we do? By adding an extra dummy template parameter that + defaults to a type in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> + namespace, we can trick ADL into finding the right operator overloads. + The solution looks like this: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Dummy</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_proto_expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_complex</span> +<span class="special">{</span> + <span class="identifier">BOOST_PROTO_EXTENDS</span><span class="special">(</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="identifier">my_complex</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span> + <span class="special">)</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">my_complex</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">c0</span><span class="special">,</span> <span class="identifier">c1</span><span class="special">;</span> + + <span class="identifier">c0</span> <span class="special">+</span> <span class="identifier">c1</span><span class="special">;</span> <span class="comment">// OK, operator+ found now!</span> +<span class="special">}</span> +</pre> +<p> + </p> +<p> + The type <code class="computeroutput"><a class="link" href="../boost/proto/is_proto_expr.html" title="Struct is_proto_expr">proto::is_proto_expr</a></code> is nothing + but an empty struct, but by making it a template parameter we make + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> an associated namespace of + <code class="computeroutput"><span class="identifier">my_complex</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>. + Now ADL can successfully find Proto's operator overloads. + </p> +</td></tr> +</table></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.expression_generators"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.expression_generators" title="Expression Generators">Expression + Generators</a> +</h5></div></div></div> +<p> + The last thing that remains to be done is to tell Proto that it needs + to wrap all of our calculator expressions in our <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> wrapper. We have already wrapped + the placeholders, but we want <span class="emphasis"><em>all</em></span> expressions that + involve the calculator placeholders to be calculators. We can do that + by specifying an expression generator when we define our <code class="computeroutput"><span class="identifier">calculator_domain</span></code>, as follows: + </p> +<pre class="programlisting"><span class="comment">// Define the calculator_domain we forward-declared above.</span> +<span class="comment">// Specify that all expression in this domain should be wrapped</span> +<span class="comment">// in the calculator<> expression wrapper.</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span> <span class="identifier">calculator</span> <span class="special">></span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The first template parameter to <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><></span></code> is the generator. "Generator" + is just a fancy name for a function object that accepts an expression + and does something to it. <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><></span></code> is a very simple one --- it wraps + an expression in the wrapper you specify. <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><></span></code> inherits from its generator parameter, + so all domains are themselves function objects. + </p> +<p> + If we used <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_EXTENDS.html" title="Macro BOOST_PROTO_EXTENDS">BOOST_PROTO_EXTENDS</a></code>()</code> + to keep our expression extension type POD, then we need to use <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pod_generator</span><span class="special"><></span></code> + instead of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><></span></code>, + as follows: + </p> +<pre class="programlisting"><span class="comment">// If calculator<> uses BOOST_PROTO_EXTENDS() instead of </span> +<span class="comment">// use proto::extends<>, use proto::pod_generator<> instead</span> +<span class="comment">// of proto::generator<>.</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">pod_generator</span><span class="special"><</span> <span class="identifier">calculator</span> <span class="special">></span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + After Proto has calculated a new expression type, it checks the domains + of the child expressions. They must match. Assuming they do, Proto creates + the new expression and passes it to <code class="computeroutput"><em class="replaceable"><code>Domain</code></em><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> for any additional processing. If we + don't specify a generator, the new expression gets passed through unchanged. + But since we've specified a generator above, <code class="computeroutput"><span class="identifier">calculator_domain</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> returns <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> objects. + </p> +<p> + Now we can use calculator expressions as function objects to STL algorithms, + as follows: + </p> +<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">data</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">1.</span><span class="special">,</span> <span class="number">2.</span><span class="special">,</span> <span class="number">3.</span><span class="special">,</span> <span class="number">4.</span><span class="special">};</span> + +<span class="comment">// Use the calculator EDSL to square each element ... WORKS! :-)</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">data</span> <span class="special">+</span> <span class="number">4</span><span class="special">,</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">_1</span> <span class="special">*</span> <span class="identifier">_1</span> <span class="special">);</span> +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.inhibiting_overloads"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.inhibiting_overloads" title="Controlling Operator Overloads">Controlling + Operator Overloads</a> +</h5></div></div></div> +<p> + By default, Proto defines every possible operator overload for Protofied + expressions. This makes it simple to bang together a EDSL. In some cases, + however, the presence of Proto's promiscuous overloads can lead to confusion + or worse. When that happens, you'll have to disable some of Proto's overloaded + operators. That is done by defining the grammar for your domain and specifying + it as the second parameter of the <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code> + template. + </p> +<p> + In the <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">Hello + Calculator</a> section, we saw an example of a Proto grammar, which + is repeated here: + </p> +<pre class="programlisting"><span class="comment">// Define the grammar of calculator expressions</span> +<span class="keyword">struct</span> <span class="identifier">calculator_grammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span> <span class="identifier">calculator_grammar</span><span class="special">,</span> <span class="identifier">calculator_grammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + We'll have much more to say about grammars in subsequent sections, but + for now, we'll just say that the <code class="computeroutput"><span class="identifier">calculator_grammar</span></code> + struct describes a subset of all expression types -- the subset that + comprise valid calculator expressions. We would like to prohibit Proto + from creating a calculator expression that does not conform to this grammar. + We do that by changing the definition of the <code class="computeroutput"><span class="identifier">calculator_domain</span></code> + struct. + </p> +<pre class="programlisting"><span class="comment">// Define the calculator_domain. Expressions in the calculator</span> +<span class="comment">// domain are wrapped in the calculator<> wrapper, and they must</span> +<span class="comment">// conform to the calculator_grammar:</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span> <span class="identifier">calculator</span> <span class="special">>,</span> <span class="bold"><strong>calculator_grammar</strong></span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The only new addition is <code class="computeroutput"><span class="identifier">calculator_grammar</span></code> + as the second template parameter to the <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code> + template. That has the effect of disabling any of Proto's operator overloads + that would create an invalid calculator expression. + </p> +<p> + Another common use for this feature would be to disable Proto's unary + <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code> + overload. It may be surprising for users of your EDSL that they cannot + take the address of their expressions! You can very easily disable Proto's + unary <code class="computeroutput"><span class="keyword">operator</span><span class="special">&</span></code> + overload for your domain with a very simple grammar, as below: + </p> +<pre class="programlisting"><span class="comment">// For expressions in my_domain, disable Proto's</span> +<span class="comment">// unary address-of operator.</span> +<span class="keyword">struct</span> <span class="identifier">my_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span> <span class="identifier">my_wrapper</span> <span class="special">></span> + <span class="comment">// A simple grammar that matches any expression that</span> + <span class="comment">// is not a unary address-of expression.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">address_of</span><span class="special"><</span> <span class="identifier">_</span> <span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The type <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">address_of</span><span class="special"><</span> + <span class="identifier">_</span> <span class="special">></span> + <span class="special">></span></code> is a very simple grammar + that matches all expressions except unary address-of expressions. In + the section describing Proto's intermediate form, we'll have much more + to say about grammars. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child" title="Controlling How Child Expressions Are Captured">Controlling + How Child Expressions Are Captured</a> +</h5></div></div></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + This is an advanced topic. Feel free to skip this if you're just getting + started with Proto. + </p></td></tr> +</table></div> +<p> + Proto's operator overloads build expressions from sub-expressions. The + sub-expressions become children of the new expression. By default, the + children are stored in the parent by reference. This section describes + how to change that default. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.h0"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.primer___literal_as_child__literal__vs___literal_as_expr__literal_"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.primer___literal_as_child__literal__vs___literal_as_expr__literal_">Primer: + <code class="literal">as_child</code> vs. <code class="literal">as_expr</code></a> + </h6> +<p> + Proto lets you independently customize the behavior of <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code>. + Both accept an object <code class="literal">x</code> and return a Proto expression + by turning <code class="literal">x</code> it into a Proto terminal if necessary. + Although similar, the two functions are used in different situations + and have subtly different behavior by default. It's important to understand + the difference so that you know which to customize to achieve the behavior + you want. + </p> +<p> + To wit: <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> is typically used by + <span class="emphasis"><em>you</em></span> to turn an object into a Proto expression that + is to be held in a local variable, as so: + </p> +<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// Turn x into a Proto expression, hold the result in a local</span> +</pre> +<p> + The above works regardless of whether <code class="computeroutput"><span class="identifier">x</span></code> + is already a Proto expression or not. The object <code class="computeroutput"><span class="identifier">l</span></code> + is guaranteed to be a valid Proto expression. If <code class="computeroutput"><span class="identifier">x</span></code> + is a non-Proto object, it is turned into a terminal expression that holds + <code class="computeroutput"><span class="identifier">x</span></code> <span class="emphasis"><em>by value</em></span>.<sup>[<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.f0" href="#ftn.boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.f0" class="footnote">4</a>]</sup> If <code class="computeroutput"><span class="identifier">x</span></code> is a + Proto object already, <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> + returns it <span class="emphasis"><em>by value</em></span> unmodified. + </p> +<p> + In contrast, <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + is used internally by Proto to pre-process objects before making them + children of another expression. Since it's internal to Proto, you don't + see it explicitly, but it's there behind the scenes in expressions like + this: + </p> +<pre class="programlisting"><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> <span class="comment">// Consider that y is a Proto expression, but x may or may not be.</span> +</pre> +<p> + In this case, Proto builds a plus node from the two children. Both are + pre-processed by passing them to <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + before making them children of the new node. If <code class="computeroutput"><span class="identifier">x</span></code> + is not a Proto expression, it becomes one by being wrapped in a Proto + terminal that holds it <span class="emphasis"><em>by reference</em></span>. If <code class="computeroutput"><span class="identifier">x</span></code> is already a Proto expression, <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> returns it <span class="emphasis"><em>by + reference</em></span> unmodified. Contrast this with the above description + for <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code>. + </p> +<p> + The table below summarizes the above description. + </p> +<div class="table"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.t0"></a><p class="title"><b>Table 20.3. proto::as_expr() vs. proto::as_child()</b></p> +<div class="table-contents"><table class="table" summary="proto::as_expr() vs. proto::as_child()"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + <span class="bold"><strong>Function</strong></span> + </p> + </th> +<th> + <p> + <span class="bold"><strong>When <code class="literal">t</code> is not a Proto + expr...</strong></span> + </p> + </th> +<th> + <p> + <span class="bold"><strong>When <code class="literal">t</code> is a Proto + expr...</strong></span> + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="literal">proto::as_expr(t)</code> + </p> + </td> +<td> + <p> + Return (by value) a new Proto terminal holding <code class="literal">t</code> + by value. + </p> + </td> +<td> + <p> + Return <code class="literal">t</code> by value unmodified. + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="literal">proto::as_child(t)</code> + </p> + </td> +<td> + <p> + Return (by value) a new Proto terminal holding <code class="literal">t</code> + by reference. + </p> + </td> +<td> + <p> + Return <code class="literal">t</code> by reference unmodified. + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + There is one important place where Proto uses both <code class="computeroutput"><span class="identifier">as_expr</span></code> + <span class="emphasis"><em>and</em></span> <code class="computeroutput"><span class="identifier">as_child</span></code>: + <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code>. The <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code> function requires + you to specify for each child whether it should be held by value or + by reference. Proto uses <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> + to pre-process the children to be held by value, and <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> for the ones to be + held by reference. + </p></td></tr> +</table></div> +<p> + Now that you know what <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + and <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> are, where they are + used, and what they do by default, you may decide that one or both of + these functions should have different behavior for your domain. For instance, + given the above description of <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code>, + the following code is always wrong: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">i</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> +<span class="keyword">auto</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">i</span> <span class="special">+</span> <span class="number">42</span><span class="special">;</span> <span class="comment">// This is WRONG! Don't do this.</span> +</pre> +<p> + Why is this wrong? Because <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + will turn the integer literal 42 into a Proto terminal that holds a reference + to a temporary integer initialized with 42. The lifetime of that temporary + ends at the semicolon, guaranteeing that the local <code class="computeroutput"><span class="identifier">l</span></code> + is left holding a dangling reference to a deceased integer. What to do? + One answer is to use <code class="computeroutput"><a class="link" href="../boost/proto/deep_copy_id1493807.html" title="Function template deep_copy">proto::deep_copy()</a></code>. + Another is to customize the behavior of <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> + for your domain. Read on for the details. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.h1"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.per_domain__literal_as_child__literal_"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.per_domain__literal_as_child__literal_">Per-Domain + <code class="literal">as_child</code></a> + </h6> +<p> + To control how Proto builds expressions out of sub-expressions in your + domain, define your domain as usual, and then define a nested <code class="computeroutput"><span class="identifier">as_child</span><span class="special"><></span></code> + class template within it, as follows: + </p> +<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">my_generator</span><span class="special">,</span> <span class="identifier">my_grammar</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// Here is where you define how Proto should handle</span> + <span class="comment">// sub-expressions that are about to be glommed into</span> + <span class="comment">// a larger expression.</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">as_child</span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="emphasis"><em><code class="literal">unspecified-Proto-expr-type</code></em></span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">T</span> <span class="special">&</span> <span class="identifier">t</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="emphasis"><em><code class="literal">unspecified-Proto-expr-object</code></em></span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> +<span class="special">};</span> +</pre> +<p> + There's one important thing to note: in the above code, the template + parameter <code class="literal">T</code> may or may not be a Proto expression type, + but the result <span class="emphasis"><em>must</em></span> be a Proto expression type, + or a reference to one. That means that most user-defined <code class="literal">as_child<></code> + templates will need to check whether <code class="literal">T</code> is an expression + or not (using <code class="computeroutput"><a class="link" href="../boost/proto/is_expr.html" title="Struct template is_expr">proto::is_expr<></a></code>), and then turn non-expressions + into Proto terminals by wrapping them as <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="comment">/* ... */</span> + <span class="special">>::</span><span class="identifier">type</span></code> + or equivalent. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.h2"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.per_domain__literal_as_expr__literal_"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.per_domain__literal_as_expr__literal_">Per-Domain + <code class="literal">as_expr</code></a> + </h6> +<p> + Although less common, Proto also lets you customize the behavior of + <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> on a per-domain basis. + The technique is identical to that for <code class="literal">as_child</code>. See + below: + </p> +<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">my_generator</span><span class="special">,</span> <span class="identifier">my_grammar</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// Here is where you define how Proto should handle</span> + <span class="comment">// objects that are to be turned into expressions</span> + <span class="comment">// fit for storage in local variables.</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">as_expr</span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="emphasis"><em><code class="literal">unspecified-Proto-expr-type</code></em></span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">T</span> <span class="special">&</span> <span class="identifier">t</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="emphasis"><em><code class="literal">unspecified-Proto-expr-object</code></em></span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> +<span class="special">};</span> +</pre> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.h3"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.making_proto_expressions__literal_auto__literal__safe"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.making_proto_expressions__literal_auto__literal__safe">Making + Proto Expressions <code class="literal">auto</code>-safe</a> + </h6> +<p> + Let's look again at the problem described above involving the C++11 + <code class="computeroutput"><span class="keyword">auto</span></code> keyword and the default + behavior of <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code>. + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">i</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> +<span class="keyword">auto</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">i</span> <span class="special">+</span> <span class="number">42</span><span class="special">;</span> <span class="comment">// This is WRONG! Don't do this.</span> +</pre> +<p> + Recall that the problem is the lifetime of the temporary integer created + to hold the value 42. The local <code class="computeroutput"><span class="identifier">l</span></code> + will be left holding a dangling reference to it after its lifetime is + over. What if we want Proto to make expressions safe to store this way + in local variables? We can do so very easily by making <code class="computeroutput"><a class="link" href="../boost/proto/as_child_id1527575.html" title="Function as_child">proto::as_child()</a></code> behave just like <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code>. The following code + achieves this: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">E</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_expr</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">my_generator</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">pod_generator</span><span class="special"><</span> <span class="identifier">my_expr</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">my_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span> <span class="identifier">my_generator</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// Make as_child() behave like as_expr() in my_domain.</span> + <span class="comment">// (proto_base_domain is a typedef for proto::domain< my_generator ></span> + <span class="comment">// that is defined in proto::domain<>.)</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">as_child</span> + <span class="special">:</span> <span class="identifier">proto_base_domain</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span> <span class="identifier">T</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">E</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">my_expr</span> +<span class="special">{</span> + <span class="identifier">BOOST_PROTO_EXTENDS</span><span class="special">(</span> <span class="identifier">E</span><span class="special">,</span> <span class="identifier">my_expr</span><span class="special"><</span> <span class="identifier">E</span> <span class="special">>,</span> <span class="identifier">my_domain</span> <span class="special">)</span> +<span class="special">};</span> + +<span class="comment">/* ... */</span> + +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">my_domain</span> <span class="special">></span> <span class="identifier">i</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> +<span class="keyword">auto</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">i</span> <span class="special">+</span> <span class="number">42</span><span class="special">;</span> <span class="comment">// OK! Everything is stored by value here.</span> +</pre> +<p> + Notice that <code class="computeroutput"><span class="identifier">my_domain</span><span class="special">::</span><span class="identifier">as_child</span><span class="special"><></span></code> simply defers to the default + implementation of <code class="computeroutput"><span class="identifier">as_expr</span><span class="special"><></span></code> found in <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code>. + By simply cross-wiring our domain's <code class="computeroutput"><span class="identifier">as_child</span><span class="special"><></span></code> to <code class="computeroutput"><span class="identifier">as_expr</span><span class="special"><></span></code>, we guarantee that all terminals + that can be held by value are, and that all child expressions are also + held by value. This increases copying and may incur a runtime performance + cost, but it eliminates any spector of lifetime management issues. + </p> +<p> + For another example, see the definition of <code class="computeroutput"><span class="identifier">lldomain</span></code> + in <code class="literal">libs/proto/example/lambda.hpp</code>. That example is + a complete reimplementation of the Boost Lambda Library (BLL) on top + of Boost.Proto. The function objects the BLL generates are safe to be + stored in local variables. To emulate this with Proto, the <code class="computeroutput"><span class="identifier">lldomain</span></code> cross-wires <code class="computeroutput"><span class="identifier">as_child</span><span class="special"><></span></code> + to <code class="computeroutput"><span class="identifier">as_expr</span><span class="special"><></span></code> + as above, but with one extra twist: objects with array type are also + stored by reference. Check it out. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains" title="EDSL Interoperatability: Sub-Domains">EDSL + Interoperatability: Sub-Domains</a> +</h5></div></div></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + This is an advanced topic. Feel free to skip this if you're just getting + started with Proto. + </p></td></tr> +</table></div> +<p> + The ability to <span class="emphasis"><em>compose</em></span> different EDSLs is one of + their most exciting features. Consider how you build a parser using yacc. + You write your grammar rules in yacc's domain-specific language. Then + you embed semantic actions written in C within your grammar. Boost's + Spirit parser generator gives you the same ability. You write grammar + rules using Spirit.Qi and embed semantic actions using the Phoenix library. + Phoenix and Spirit are both Proto-based domain-specific languages with + their own distinct syntax and semantics. But you can freely embed Phoenix + expressions within Spirit expressions. This section describes Proto's + <span class="emphasis"><em>sub-domain</em></span> feature that lets you define families + of interoperable domains. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.h0"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.dueling_domains"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.dueling_domains">Dueling + Domains</a> + </h6> +<p> + When you try to create an expression from two sub-expressions in different + domains, what is the domain of the resulting expression? This is the + fundamental problem that is addressed by sub-domains. Consider the following + code: + </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">proto</span><span class="special">/</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> + +<span class="comment">// Forward-declare two expression wrappers</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">E</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">spirit_expr</span><span class="special">;</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">E</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">phoenix_expr</span><span class="special">;</span> + +<span class="comment">// Define two domains</span> +<span class="keyword">struct</span> <span class="identifier">spirit_domain</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">spirit_expr</span><span class="special">></span> <span class="special">></span> <span class="special">{};</span> +<span class="keyword">struct</span> <span class="identifier">phoenix_domain</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">phoenix_expr</span><span class="special">></span> <span class="special">></span> <span class="special">{};</span> + +<span class="comment">// Implement the two expression wrappers</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">E</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">spirit_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">E</span><span class="special">,</span> <span class="identifier">spirit_expr</span><span class="special"><</span><span class="identifier">E</span><span class="special">>,</span> <span class="identifier">spirit_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">spirit_expr</span><span class="special">(</span><span class="identifier">E</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">e</span> <span class="special">=</span> <span class="identifier">E</span><span class="special">())</span> <span class="special">:</span> <span class="identifier">spirit_expr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">e</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">E</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">phoenix_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">E</span><span class="special">,</span> <span class="identifier">phoenix_expr</span><span class="special"><</span><span class="identifier">E</span><span class="special">>,</span> <span class="identifier">phoenix_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">phoenix_expr</span><span class="special">(</span><span class="identifier">E</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">e</span> <span class="special">=</span> <span class="identifier">E</span><span class="special">())</span> <span class="special">:</span> <span class="identifier">phoenix_expr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span> <span class="special">{}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">spirit_domain</span><span class="special">></span> <span class="identifier">sp</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">phoenix_domain</span><span class="special">></span> <span class="identifier">phx</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> + + <span class="comment">// Whoops! What does it mean to add two expressions in different domains?</span> + <span class="identifier">sp</span> <span class="special">+</span> <span class="identifier">phx</span><span class="special">;</span> <span class="comment">// ERROR</span> +<span class="special">}</span> +</pre> +<p> + Above, we define two domains called <code class="computeroutput"><span class="identifier">spirit_domain</span></code> + and <code class="computeroutput"><span class="identifier">phoenix_domain</span></code> and + declare two int literals in each. Then we try to compose them into a + larger expression using Proto's binary plus operator, and it fails. Proto + can't figure out whether the resulting expression should be in the Spirit + domain or the Phoenix domain, and thus whether it should be an instance + of <code class="computeroutput"><span class="identifier">spirit_expr</span><span class="special"><></span></code> + or <code class="computeroutput"><span class="identifier">phoenix_expr</span><span class="special"><></span></code>. + We have to tell Proto how to resolve the conflict. We can do that by + declaring that Phoenix is a sub-domain of Spirit as in the following + definition of <code class="computeroutput"><span class="identifier">phoenix_domain</span></code>: + </p> +<pre class="programlisting"><span class="comment">// Declare that phoenix_domain is a sub-domain of spirit_domain</span> +<span class="keyword">struct</span> <span class="identifier">phoenix_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">phoenix_expr</span><span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">,</span> <span class="bold"><strong>spirit_domain</strong></span><span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The third template parameter to <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code> + is the super-domain. By defining <code class="computeroutput"><span class="identifier">phoenix_domain</span></code> + as above, we are saying that Phoenix expressions can be combined with + Spirit expressions, and that when that happens, the resulting expression + should be a Spirit expression. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + If you are wondering what the purpose of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> + is in the definition of <code class="computeroutput"><span class="identifier">phoenix_domain</span></code> + above, recall that the second template parameter to <code class="computeroutput"><a class="link" href="../boost/proto/domain.html" title="Struct template domain">proto::domain<></a></code> + is the domain's grammar. <span class="quote">“<span class="quote"><code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code></span>”</span> + is the default and signifies that the domain places no restrictions + on the expressions that are valid within it. + </p></td></tr> +</table></div> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.h1"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.domain_resolution"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.domain_resolution">Domain + Resolution</a> + </h6> +<p> + When there are multiple domains in play within a given expression, Proto + uses some rules to figure out which domain "wins". The rules + are loosely modeled on the rules for C++ inheritance. <code class="computeroutput"><span class="identifier">Phoenix_domain</span></code> + is a sub-domain of <code class="computeroutput"><span class="identifier">spirit_domain</span></code>. + You can liken that to a derived/base relationship that gives Phoenix + expressions a kind of implicit conversion to Spirit expressions. And + since Phoenix expressions can be "converted" to Spirit expressions, + they can be freely combined with Spirit expressions and the result is + a Spirit expression. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + Super- and sub-domains are not actually implemented using inheritance. + This is only a helpful mental model. + </p></td></tr> +</table></div> +<p> + The analogy with inheritance holds even in the case of three domains + when two are sub-domains of the third. Imagine another domain called + <code class="computeroutput"><span class="identifier">foobar_domain</span></code> that was + also a sub-domain of <code class="computeroutput"><span class="identifier">spirit_domain</span></code>. + Expressions in the <code class="computeroutput"><span class="identifier">foobar_domain</span></code> + could be combined with expressions in the <code class="computeroutput"><span class="identifier">phoenix_domain</span></code> + and the resulting expression would be in the <code class="computeroutput"><span class="identifier">spirit_domain</span></code>. + That's because expressions in the two sub-domains both have "conversions" + to the super-domain, so the operation is allowed and the super-domain + wins. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.h2"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.the_default_domain"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.the_default_domain">The + Default Domain</a> + </h6> +<p> + When you don't assign a Proto expression to a particular domain, Proto + considers it a member of the so-called default domain, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span></code>. Even non-Proto objects + are treated as terminals in the default domain. Consider: + </p> +<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">spirit_domain</span><span class="special">></span> <span class="identifier">sp</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> + + <span class="comment">// Add 1 to a spirit expression. Result is a spirit expression.</span> + <span class="identifier">sp</span> <span class="special">+</span> <span class="number">1</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + Expressions in the default domain (or non-expressions like <code class="literal">1</code>) + have a kind of implicit conversion to expressions every other domain + type. What's more, you can define your domain to be a sub-domain of the + default domain. In so doing, you give expressions in your domain conversions + to expressions in every other domain. This is like a <span class="quote">“<span class="quote">free love</span>”</span> + domain, because it will freely mix with all other domains. + </p> +<p> + Let's think again about the Phoenix EDSL. Since it provides generally + useful lambda functionality, it's reasonable to assume that lots of other + EDSLs besides Spirit might want the ability to embed Phoenix expressions. + In other words, <code class="computeroutput"><span class="identifier">phoenix_domain</span></code> + should be a sub-domain of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span></code>, + not <code class="computeroutput"><span class="identifier">spirit_domain</span></code>: + </p> +<pre class="programlisting"><span class="comment">// Declare that phoenix_domain is a sub-domain of proto::default_domain</span> +<span class="keyword">struct</span> <span class="identifier">phoenix_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">phoenix_expr</span><span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span><span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + That's much better. Phoenix expressions can now be put anywhere. + </p> +<h6> +<a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.h3"></a> + <span><a name="boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.sub_domain_summary"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.subdomains.sub_domain_summary">Sub-Domain + Summary</a> + </h6> +<p> + Use Proto sub-domains to make it possible to mix expressions from multiple + domains. And when you want expressions in your domain to freely combine + with <span class="emphasis"><em>all</em></span> expressions, make it a sub-domain of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span></code>. + </p> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.front_end.define_operators"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.define_operators" title="Adapting Existing Types to Proto">Adapting + Existing Types to Proto</a> +</h4></div></div></div> +<p> + The preceding discussions of defining Proto front ends have all made a + big assumption: that you have the luxury of defining everything from scratch. + What happens if you have existing types, say a matrix type and a vector + type, that you would like to treat as if they were Proto terminals? Proto + usually trades only in its own expression types, but with <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_DEFINE_OPERATORS.html" title="Macro BOOST_PROTO_DEFINE_OPERATORS">BOOST_PROTO_DEFINE_OPERATORS</a></code>()</code>, + it can accomodate your custom terminal types, too. + </p> +<p> + Let's say, for instance, that you have the following types and that you + can't modify then to make them <span class="quote">“<span class="quote">native</span>”</span> Proto terminal types. + </p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">math</span> +<span class="special">{</span> + <span class="comment">// A matrix type ...</span> + <span class="keyword">struct</span> <span class="identifier">matrix</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span> + + <span class="comment">// A vector type ...</span> + <span class="keyword">struct</span> <span class="identifier">vector</span> <span class="special">{</span> <span class="comment">/*...*/</span> <span class="special">};</span> +<span class="special">}</span> +</pre> +<p> + You can non-intrusively make objects of these types Proto terminals by + defining the proper operator overloads using <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_DEFINE_OPERATORS.html" title="Macro BOOST_PROTO_DEFINE_OPERATORS">BOOST_PROTO_DEFINE_OPERATORS</a></code>()</code>. + The basic procedure is as follows: + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + Define a trait that returns true for your types and false for all others. + </li> +<li class="listitem"> + Reopen the namespace of your types and use <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_DEFINE_OPERATORS.html" title="Macro BOOST_PROTO_DEFINE_OPERATORS">BOOST_PROTO_DEFINE_OPERATORS</a></code>()</code> + to define a set of operator overloads, passing the name of the trait + as the first macro parameter, and the name of a Proto domain (e.g., + <code class="computeroutput"><a class="link" href="../boost/proto/default_domain.html" title="Struct default_domain">proto::default_domain</a></code>) + as the second. + </li> +</ol></div> +<p> + The following code demonstrates how it works. + </p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">math</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">is_terminal</span> + <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">false_</span> + <span class="special">{};</span> + + <span class="comment">// OK, "matrix" is a custom terminal type</span> + <span class="keyword">template</span><span class="special"><></span> + <span class="keyword">struct</span> <span class="identifier">is_terminal</span><span class="special"><</span><span class="identifier">matrix</span><span class="special">></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="comment">// OK, "vector" is a custom terminal type</span> + <span class="keyword">template</span><span class="special"><></span> + <span class="keyword">struct</span> <span class="identifier">is_terminal</span><span class="special"><</span><span class="identifier">vector</span><span class="special">></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="comment">// Define all the operator overloads to construct Proto</span> + <span class="comment">// expression templates, treating "matrix" and "vector"</span> + <span class="comment">// objects as if they were Proto terminals.</span> + <span class="identifier">BOOST_PROTO_DEFINE_OPERATORS</span><span class="special">(</span><span class="identifier">is_terminal</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_domain</span><span class="special">)</span> +<span class="special">}</span> +</pre> +<p> + The invocation of the <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_DEFINE_OPERATORS.html" title="Macro BOOST_PROTO_DEFINE_OPERATORS">BOOST_PROTO_DEFINE_OPERATORS</a></code>()</code> + macro defines a complete set of operator overloads that treat <code class="computeroutput"><span class="identifier">matrix</span></code> and <code class="computeroutput"><span class="identifier">vector</span></code> + objects as if they were Proto terminals. And since the operators are defined + in the same namespace as the <code class="computeroutput"><span class="identifier">matrix</span></code> + and <code class="computeroutput"><span class="identifier">vector</span></code> types, the operators + will be found by argument-dependent lookup. With the code above, we can + now construct expression templates with matrices and vectors, as shown + below. + </p> +<pre class="programlisting"><span class="identifier">math</span><span class="special">::</span><span class="identifier">matrix</span> <span class="identifier">m1</span><span class="special">;</span> +<span class="identifier">math</span><span class="special">::</span><span class="identifier">vector</span> <span class="identifier">v1</span><span class="special">;</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">i</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> + +<span class="identifier">m1</span> <span class="special">*</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// custom terminal and literals are OK</span> +<span class="identifier">m1</span> <span class="special">*</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// custom terminal and Proto expressions are OK</span> +<span class="identifier">m1</span> <span class="special">*</span> <span class="identifier">v1</span><span class="special">;</span> <span class="comment">// two custom terminals are OK, too.</span> +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.front_end.code_repetition"></a><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.code_repetition" title="Generating Repetitive Code with the Preprocessor">Generating + Repetitive Code with the Preprocessor</a> +</h4></div></div></div> +<p> + Sometimes as a EDSL designer, to make the lives of your users easy, you + have to make your own life hard. Giving your users natural and flexible + syntax often involves writing large numbers of repetitive function overloads. + It can be enough to give you repetitive stress injury! Before you hurt + yourself, check out the macros Proto provides for automating many repetitive + code-generation chores. + </p> +<p> + Imagine that we are writing a lambda EDSL, and we would like to enable + syntax for constructing temporary objects of any type using the following + syntax: + </p> +<pre class="programlisting"><span class="comment">// A lambda expression that takes two arguments and</span> +<span class="comment">// uses them to construct a temporary std::complex<></span> +<span class="identifier">construct</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>(</span> <span class="identifier">_1</span><span class="special">,</span> <span class="identifier">_2</span> <span class="special">)</span> +</pre> +<p> + For the sake of the discussion, imagine that we already have a function + object template <code class="computeroutput"><span class="identifier">construct_impl</span><span class="special"><></span></code> that accepts arguments and constructs + new objects from them. We would want the above lambda expression to be + equivalent to the following: + </p> +<pre class="programlisting"><span class="comment">// The above lambda expression should be roughly equivalent</span> +<span class="comment">// to the following:</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span><span class="special">>(</span> + <span class="identifier">construct_impl</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>()</span> <span class="comment">// The function to invoke lazily</span> + <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">_1</span><span class="special">)</span> <span class="comment">// The first argument to the function</span> + <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">_2</span><span class="special">)</span> <span class="comment">// The second argument to the function</span> +<span class="special">);</span> +</pre> +<p> + We can define our <code class="computeroutput"><span class="identifier">construct</span><span class="special">()</span></code> function template as follows: + </p> +<pre class="programlisting"><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">typename</span> <span class="identifier">A0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A1</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span> + <span class="special">,</span> <span class="identifier">construct_impl</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&</span> + <span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> +<span class="identifier">construct</span><span class="special">(</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a1</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span><span class="special">>(</span> + <span class="identifier">construct_impl</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span> + <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">a0</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">a1</span><span class="special">)</span> + <span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + This works for two arguments, but we would like it to work for any number + of arguments, up to ( <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_MAX_ARITY.html" title="Macro BOOST_PROTO_MAX_ARITY">BOOST_PROTO_MAX_ARITY</a></code></code> + - 1). (Why "- 1"? Because one child is taken up by the <code class="computeroutput"><span class="identifier">construct_impl</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span></code> + terminal leaving room for only ( <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_MAX_ARITY.html" title="Macro BOOST_PROTO_MAX_ARITY">BOOST_PROTO_MAX_ARITY</a></code></code> + - 1) other children.) + </p> +<p> + For cases like this, Proto provides the <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT.html" title="Macro BOOST_PROTO_REPEAT">BOOST_PROTO_REPEAT</a></code>()</code> + and <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO">BOOST_PROTO_REPEAT_FROM_TO</a></code>()</code> + macros. To use it, we turn the function definition above into a macro as + follows: + </p> +<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">M0</span><span class="special">(</span><span class="identifier">N</span><span class="special">,</span> <span class="identifier">typename_A</span><span class="special">,</span> <span class="identifier">A_const_ref</span><span class="special">,</span> <span class="identifier">A_const_ref_a</span><span class="special">,</span> <span class="identifier">ref_a</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="identifier">typename_A</span><span class="special">(</span><span class="identifier">N</span><span class="special">)></span> <span class="special">\</span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span> <span class="special">\</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">construct_impl</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">A_const_ref</span><span class="special">(</span><span class="identifier">N</span><span class="special">)</span> <span class="special">\</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="special">\</span> +<span class="identifier">construct</span><span class="special">(</span><span class="identifier">A_const_ref_a</span><span class="special">(</span><span class="identifier">N</span><span class="special">))</span> <span class="special">\</span> +<span class="special">{</span> <span class="special">\</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span><span class="special">>(</span> <span class="special">\</span> + <span class="identifier">construct_impl</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">ref_a</span><span class="special">(</span><span class="identifier">N</span><span class="special">)</span> <span class="special">\</span> + <span class="special">);</span> <span class="special">\</span> +<span class="special">}</span> +</pre> +<p> + Notice that we turned the function into a macro that takes 5 arguments. + The first is the current iteration number. The rest are the names of other + macros that generate different sequences. For instance, Proto passes as + the second parameter the name of a macro that will expand to <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">A0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A1</span><span class="special">,</span> <span class="special">...</span></code>. + </p> +<p> + Now that we have turned our function into a macro, we can pass the macro + to <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO">BOOST_PROTO_REPEAT_FROM_TO</a></code>()</code>. + Proto will invoke it iteratively, generating all the function overloads + for us. + </p> +<pre class="programlisting"><span class="comment">// Generate overloads of construct() that accept from</span> +<span class="comment">// 1 to BOOST_PROTO_MAX_ARITY-1 arguments:</span> +<span class="identifier">BOOST_PROTO_REPEAT_FROM_TO</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">BOOST_PROTO_MAX_ARITY</span><span class="special">,</span> <span class="identifier">M0</span><span class="special">)</span> +<span class="preprocessor">#undef</span> <span class="identifier">M0</span> +</pre> +<h6> +<a name="boost_proto.users_guide.front_end.code_repetition.h0"></a> + <span><a name="boost_proto.users_guide.front_end.code_repetition.non_default_sequences"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.front_end.code_repetition.non_default_sequences">Non-Default + Sequences</a> + </h6> +<p> + As mentioned above, Proto passes as the last 4 arguments to your macro + the names of other macros that generate various sequences. The macros + <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT.html" title="Macro BOOST_PROTO_REPEAT">BOOST_PROTO_REPEAT</a></code>()</code> + and <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO">BOOST_PROTO_REPEAT_FROM_TO</a></code>()</code> + select defaults for these parameters. If the defaults do not meet your + needs, you can use <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_EX.html" title="Macro BOOST_PROTO_REPEAT_EX">BOOST_PROTO_REPEAT_EX</a></code>()</code> + and <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO_EX.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO_EX">BOOST_PROTO_REPEAT_FROM_TO_EX</a></code>()</code> + and pass different macros that generate different sequences. Proto defines + a number of such macros for use as parameters to <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_EX.html" title="Macro BOOST_PROTO_REPEAT_EX">BOOST_PROTO_REPEAT_EX</a></code>()</code> + and <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT_FROM_TO_EX.html" title="Macro BOOST_PROTO_REPEAT_FROM_TO_EX">BOOST_PROTO_REPEAT_FROM_TO_EX</a></code>()</code>. + Check the reference section for <code class="computeroutput"><a class="link" href="reference.html#header.boost.proto.repeat_hpp" title="Header <boost/proto/repeat.hpp>">boost/proto/repeat.hpp</a></code> + for all the details. + </p> +<p> + Also, check out <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_LOCAL_ITERATE.html" title="Macro BOOST_PROTO_LOCAL_ITERATE">BOOST_PROTO_LOCAL_ITERATE</a></code>()</code>. + It works similarly to <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_REPEAT.html" title="Macro BOOST_PROTO_REPEAT">BOOST_PROTO_REPEAT</a></code>()</code> + and friends, but it can be easier to use when you want to change one macro + argument and accept defaults for the others. + </p> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.intermediate_form"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form" title="Intermediate Form: Understanding and Introspecting Expressions">Intermediate + Form: Understanding and Introspecting Expressions</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.left_right_child">Accessing + Parts of an Expression</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.deep_copying_expressions">Deep-copying + Expressions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.debugging_expressions">Debugging + Expressions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.tags_and_metafunctions">Operator + Tags and Metafunctions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expressions_as_fusion_sequences">Expressions + as Fusion Sequences</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection">Expression + Introspection: Defining a Grammar</a></span></dt> +</dl></div> +<p> + By now, you know a bit about how to build a front-end for your EDSL "compiler" + -- you can define terminals and functions that generate expression templates. + But we haven't said anything about the expression templates themselves. What + do they look like? What can you do with them? In this section we'll see. + </p> +<h5> +<a name="boost_proto.users_guide.intermediate_form.h0"></a> + <span><a name="boost_proto.users_guide.intermediate_form.the__literal_expr_lt__gt___literal__type"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.the__literal_expr_lt__gt___literal__type">The + <code class="literal">expr<></code> Type</a> + </h5> +<p> + All Proto expressions are an instantiation of a template called <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> (or a wrapper around + such an instantiation). When we define a terminal as below, we are really + initializing an instance of the <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> + template. + </p> +<pre class="programlisting"><span class="comment">// Define a placeholder type</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">placeholder</span> +<span class="special">{};</span> + +<span class="comment">// Define the Protofied placeholder terminal</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> +</pre> +<p> + The actual type of <code class="computeroutput"><span class="identifier">_1</span></code> looks + like this: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">term</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>,</span> <span class="number">0</span> <span class="special">></span> +</pre> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> template is the most + important type in Proto. Although you will rarely need to deal with it directly, + it's always there behind the scenes holding your expression trees together. + In fact, <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> <span class="emphasis"><em>is</em></span> + the expression tree -- branches, leaves and all. + </p> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> template makes up the + nodes in expression trees. The first template parameter is the node type; + in this case, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span></code>. + That means that <code class="computeroutput"><span class="identifier">_1</span></code> is a leaf-node + in the expression tree. The second template parameter is a list of child + types, or in the case of terminals, the terminal's value type. Terminals + will always have only one type in the type list. The last parameter is the + arity of the expression. Terminals have arity 0, unary expressions have arity + 1, etc. + </p> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> struct is defined as + follows: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Args</span><span class="special">,</span> <span class="keyword">long</span> <span class="identifier">Arity</span> <span class="special">=</span> <span class="identifier">Args</span><span class="special">::</span><span class="identifier">arity</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">expr</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Args</span> <span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">expr</span><span class="special"><</span> <span class="identifier">Tag</span><span class="special">,</span> <span class="identifier">Args</span><span class="special">,</span> <span class="number">1</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">Args</span><span class="special">::</span><span class="identifier">child0</span> <span class="identifier">proto_child0</span><span class="special">;</span> + <span class="identifier">proto_child0</span> <span class="identifier">child0</span><span class="special">;</span> + <span class="comment">// ...</span> +<span class="special">};</span> +</pre> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> struct does not define + a constructor, or anything else that would prevent static initialization. + All <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> objects are initialized + using <span class="emphasis"><em>aggregate initialization</em></span>, with curly braces. In + our example, <code class="computeroutput"><span class="identifier">_1</span></code> is initialized + with the initializer <code class="computeroutput"><span class="special">{{}}</span></code>. The + outer braces are the initializer for the <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code> + struct, and the inner braces are for the member <code class="computeroutput"><span class="identifier">_1</span><span class="special">.</span><span class="identifier">child0</span></code> + which is of type <code class="computeroutput"><span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span></code>. + Note that we use braces to initialize <code class="computeroutput"><span class="identifier">_1</span><span class="special">.</span><span class="identifier">child0</span></code> + because <code class="computeroutput"><span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span></code> is also + an aggregate. + </p> +<h5> +<a name="boost_proto.users_guide.intermediate_form.h1"></a> + <span><a name="boost_proto.users_guide.intermediate_form.building_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.building_expression_trees">Building + Expression Trees</a> + </h5> +<p> + The <code class="computeroutput"><span class="identifier">_1</span></code> node is an instantiation + of <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code>, and expressions containing + <code class="computeroutput"><span class="identifier">_1</span></code> are also instantiations + of <code class="computeroutput"><a class="link" href="../boost/proto/expr.html" title="Struct template expr">proto::expr<></a></code>. To use Proto effectively, + you won't have to bother yourself with the actual types that Proto generates. + These are details, but you're likely to encounter these types in compiler + error messages, so it's helpful to be familiar with them. The types look + like this: + </p> +<pre class="programlisting"><span class="comment">// The type of the expression -_1</span> +<span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">negate</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">list1</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">term</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">></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="special">></span> + <span class="special">,</span> <span class="number">1</span> + <span class="special">></span> +<span class="identifier">negate_placeholder_type</span><span class="special">;</span> + +<span class="identifier">negate_placeholder_type</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">-</span><span class="identifier">_1</span><span class="special">;</span> + +<span class="comment">// The type of the expression _1 + 42</span> +<span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">list2</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">term</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">></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="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">term</span><span class="special"><</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&</span> <span class="special">></span> + <span class="special">,</span> <span class="number">0</span> + <span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="number">2</span> + <span class="special">></span> +<span class="identifier">placeholder_plus_int_type</span><span class="special">;</span> + +<span class="identifier">placeholder_plus_int_type</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">_1</span> <span class="special">+</span> <span class="number">42</span><span class="special">;</span> +</pre> +<p> + There are a few things to note about these types: + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + Terminals have arity zero, unary expressions have arity one and binary + expressions have arity two. + </li> +<li class="listitem"> + When one Proto expression is made a child node of another Proto expression, + it is held by reference, <span class="emphasis"><em>even if it is a temporary object</em></span>. + This last point becomes important later. + </li> +<li class="listitem"> + Non-Proto expressions, such as the integer literal, are turned into Proto + expressions by wrapping them in new <code class="computeroutput"><span class="identifier">expr</span><span class="special"><></span></code> terminal objects. These new wrappers + are not themselves held by reference, but the object wrapped <span class="emphasis"><em>is</em></span>. + Notice that the type of the Protofied <code class="computeroutput"><span class="number">42</span></code> + literal is <code class="computeroutput"><span class="keyword">int</span> <span class="keyword">const</span> + <span class="special">&</span></code> -- held by reference. + </li> +</ul></div> +<p> + The types make it clear: everything in a Proto expression tree is held by + reference. That means that building an expression tree is exceptionally cheap. + It involves no copying at all. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + An astute reader will notice that the object <code class="computeroutput"><span class="identifier">y</span></code> + defined above will be left holding a dangling reference to a temporary + int. In the sorts of high-performance applications Proto addresses, it + is typical to build and evaluate an expression tree before any temporary + objects go out of scope, so this dangling reference situation often doesn't + arise, but it is certainly something to be aware of. Proto provides utilities + for deep-copying expression trees so they can be passed around as value + types without concern for dangling references. + </p></td></tr> +</table></div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.intermediate_form.left_right_child"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.left_right_child" title="Accessing Parts of an Expression">Accessing + Parts of an Expression</a> +</h4></div></div></div> +<p> + After assembling an expression into a tree, you'll naturally want to be + able to do the reverse, and access a node's children. You may even want + to be able to iterate over the children with algorithms from the Boost.Fusion + library. This section shows how. + </p> +<h6> +<a name="boost_proto.users_guide.intermediate_form.left_right_child.h0"></a> + <span><a name="boost_proto.users_guide.intermediate_form.left_right_child.getting_expression_tags_and_arities"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.left_right_child.getting_expression_tags_and_arities">Getting + Expression Tags and Arities</a> + </h6> +<p> + Every node in an expression tree has both a <span class="emphasis"><em>tag</em></span> type + that describes the node, and an <span class="emphasis"><em>arity</em></span> corresponding + to the number of child nodes it has. You can use the <code class="computeroutput"><a class="link" href="../boost/proto/tag_of.html" title="Struct template tag_of">proto::tag_of<></a></code> + and <code class="computeroutput"><a class="link" href="../boost/proto/arity_of.html" title="Struct template arity_of">proto::arity_of<></a></code> metafunctions to fetch + them. Consider the following: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">void</span> <span class="identifier">check_plus_node</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&)</span> +<span class="special">{</span> + <span class="comment">// Assert that the tag type is proto::tag::plus</span> + <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">((</span> + <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag_of</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span> + <span class="special">>::</span><span class="identifier">value</span> + <span class="special">));</span> + + <span class="comment">// Assert that the arity is 2</span> + <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">arity_of</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">==</span> <span class="number">2</span> <span class="special">);</span> +<span class="special">}</span> + +<span class="comment">// Create a binary plus node and use check_plus_node()</span> +<span class="comment">// to verify its tag type and arity:</span> +<span class="identifier">check_plus_node</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">+</span> <span class="number">2</span> <span class="special">);</span> +</pre> +<p> + For a given type <code class="computeroutput"><span class="identifier">Expr</span></code>, + you could access the tag and arity directly as <code class="computeroutput"><span class="identifier">Expr</span><span class="special">::</span><span class="identifier">proto_tag</span></code> + and <code class="computeroutput"><span class="identifier">Expr</span><span class="special">::</span><span class="identifier">proto_arity</span></code>, where <code class="computeroutput"><span class="identifier">Expr</span><span class="special">::</span><span class="identifier">proto_arity</span></code> + is an MPL Integral Constant. + </p> +<h6> +<a name="boost_proto.users_guide.intermediate_form.left_right_child.h1"></a> + <span><a name="boost_proto.users_guide.intermediate_form.left_right_child.getting_terminal_values"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.left_right_child.getting_terminal_values">Getting + Terminal Values</a> + </h6> +<p> + There is no simpler expression than a terminal, and no more basic operation + than extracting its value. As we've already seen, that is what <code class="computeroutput"><a class="link" href="../boost/proto/value_id1528169.html" title="Function value">proto::value()</a></code> is for. + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">};</span> + +<span class="comment">// Get the value of the cout_ terminal:</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="identifier">sout</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special">);</span> + +<span class="comment">// Assert that we got back what we put in:</span> +<span class="identifier">assert</span><span class="special">(</span> <span class="special">&</span><span class="identifier">sout</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">);</span> +</pre> +<p> + To compute the return type of the <code class="computeroutput"><a class="link" href="../boost/proto/value_id1528169.html" title="Function value">proto::value()</a></code> + function, you can use <code class="computeroutput"><a class="link" href="../boost/proto/result_of/value.html" title="Struct template value">proto::result_of::value<></a></code>. + When the parameter to <code class="computeroutput"><a class="link" href="../boost/proto/result_of/value.html" title="Struct template value">proto::result_of::value<></a></code> + is a non-reference type, the result type of the metafunction is the type + of the value as suitable for storage by value; that is, top-level reference + and qualifiers are stripped from it. But when instantiated with a reference + type, the result type has a reference <span class="emphasis"><em>added</em></span> to it, + yielding a type suitable for storage by reference. If you want to know + the actual type of the terminal's value including whether it is stored + by value or reference, you can use <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_at</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="number">0</span><span class="special">>::</span><span class="identifier">type</span></code>. + </p> +<p> + The following table summarizes the above paragraph. + </p> +<div class="table"> +<a name="boost_proto.users_guide.intermediate_form.left_right_child.t0"></a><p class="title"><b>Table 20.4. Accessing Value Types</b></p> +<div class="table-contents"><table class="table" summary="Accessing Value Types"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Metafunction Invocation + </p> + </th> +<th> + <p> + When the Value Type Is ... + </p> + </th> +<th> + <p> + The Result Is ... + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_const</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> +<span class="special">>::</span><span class="identifier">type</span> <sup>[<a name="boost_proto.users_guide.intermediate_form.left_right_child.f0" href="#ftn.boost_proto.users_guide.intermediate_form.left_right_child.f0" class="footnote">a</a>]</sup></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><</span><span class="identifier">Expr</span> <span class="special">&>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><</span><span class="identifier">Expr</span> <span class="keyword">const</span> + <span class="special">&>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_reference</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_const</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> +<span class="special">>::</span><span class="identifier">type</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_at</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> + <span class="number">0</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +</tr> +</tbody> +<tbody class="footnotes"><tr><td colspan="3"><div class="footnote"><p><sup>[<a id="ftn.boost_proto.users_guide.intermediate_form.left_right_child.f0" href="#boost_proto.users_guide.intermediate_form.left_right_child.f0" class="para">a</a>] </sup>If <code class="computeroutput"><span class="identifier">T</span></code> is a reference-to-function type, then the result type is simply <code class="computeroutput"><span class="identifier">T</span></code>.</p></div></td></tr></tbody> +</table></div> +</div> +<br class="table-break"><h6> +<a name="boost_proto.users_guide.intermediate_form.left_right_child.h2"></a> + <span><a name="boost_proto.users_guide.intermediate_form.left_right_child.getting_child_expressions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.left_right_child.getting_child_expressions">Getting + Child Expressions</a> + </h6> +<p> + Each non-terminal node in an expression tree corresponds to an operator + in an expression, and the children correspond to the operands, or arguments + of the operator. To access them, you can use the <code class="computeroutput"><a class="link" href="../boost/proto/child_c_id1528008.html" title="Function child_c">proto::child_c()</a></code> + function template, as demonstrated below: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">{</span><span class="number">42</span><span class="special">};</span> + +<span class="comment">// Get the 0-th operand of an addition operation:</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="special">&</span><span class="identifier">ri</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span> <span class="identifier">i</span> <span class="special">+</span> <span class="number">2</span> <span class="special">);</span> + +<span class="comment">// Assert that we got back what we put in:</span> +<span class="identifier">assert</span><span class="special">(</span> <span class="special">&</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">ri</span> <span class="special">);</span> +</pre> +<p> + You can use the <code class="computeroutput"><a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">proto::result_of::child_c<></a></code> + metafunction to get the type of the Nth child of an expression node. Usually + you don't care to know whether a child is stored by value or by reference, + so when you ask for the type of the Nth child of an expression <code class="computeroutput"><span class="identifier">Expr</span></code> (where <code class="computeroutput"><span class="identifier">Expr</span></code> + is not a reference type), you get the child's type after references and + cv-qualifiers have been stripped from it. + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">void</span> <span class="identifier">test_result_of_child_c</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="number">0</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">type</span><span class="special">;</span> + + <span class="comment">// Since Expr is not a reference type,</span> + <span class="comment">// result_of::child_c<Expr, 0>::type is a</span> + <span class="comment">// non-cv qualified, non-reference type:</span> + <span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> + <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span> <span class="identifier">type</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> + <span class="special">));</span> +<span class="special">}</span> + +<span class="comment">// ...</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">{</span><span class="number">42</span><span class="special">};</span> +<span class="identifier">test_result_of_child_c</span><span class="special">(</span> <span class="identifier">i</span> <span class="special">+</span> <span class="number">2</span> <span class="special">);</span> +</pre> +<p> + However, if you ask for the type of the Nth child of <code class="computeroutput"><span class="identifier">Expr</span> + <span class="special">&</span></code> or <code class="computeroutput"><span class="identifier">Expr</span> + <span class="keyword">const</span> <span class="special">&</span></code> + (note the reference), the result type will be a reference, regardless of + whether the child is actually stored by reference or not. If you need to + know exactly how the child is stored in the node, whether by reference + or by value, you can use <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_at</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">N</span><span class="special">>::</span><span class="identifier">type</span></code>. The following table summarizes + the behavior of the <code class="computeroutput"><a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">proto::result_of::child_c<></a></code> + metafunction. + </p> +<div class="table"> +<a name="boost_proto.users_guide.intermediate_form.left_right_child.t1"></a><p class="title"><b>Table 20.5. Accessing Child Types</b></p> +<div class="table-contents"><table class="table" summary="Accessing Child Types"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Metafunction Invocation + </p> + </th> +<th> + <p> + When the Child Is ... + </p> + </th> +<th> + <p> + The Result Is ... + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> + <span class="identifier">N</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_const</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> +<span class="special">>::</span><span class="identifier">type</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">Expr</span> <span class="special">&,</span> + <span class="identifier">N</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">Expr</span> <span class="keyword">const</span> + <span class="special">&,</span> <span class="identifier">N</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_reference</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_const</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> +<span class="special">>::</span><span class="identifier">type</span></pre> +<p> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value_at</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> + <span class="identifier">N</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">T</span></code> + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><h6> +<a name="boost_proto.users_guide.intermediate_form.left_right_child.h3"></a> + <span><a name="boost_proto.users_guide.intermediate_form.left_right_child.common_shortcuts"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.left_right_child.common_shortcuts">Common + Shortcuts</a> + </h6> +<p> + Most operators in C++ are unary or binary, so accessing the only operand, + or the left and right operands, are very common operations. For this reason, + Proto provides the <code class="computeroutput"><a class="link" href="../boost/proto/child_id1527766.html" title="Function child">proto::child()</a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/left_id1528275.html" title="Function left">proto::left()</a></code>, and <code class="computeroutput"><a class="link" href="../boost/proto/right_id1528399.html" title="Function right">proto::right()</a></code> + functions. <code class="computeroutput"><a class="link" href="../boost/proto/child_id1527766.html" title="Function child">proto::child()</a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/left_id1528275.html" title="Function left">proto::left()</a></code> + are synonymous with <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">0</span><span class="special">>()</span></code>, + and <code class="computeroutput"><a class="link" href="../boost/proto/right_id1528399.html" title="Function right">proto::right()</a></code> is synonymous with <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">1</span><span class="special">>()</span></code>. + </p> +<p> + There are also <code class="computeroutput"><a class="link" href="../boost/proto/result_of/child.html" title="Struct template child">proto::result_of::child<></a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/result_of/left.html" title="Struct template left">proto::result_of::left<></a></code>, and <code class="computeroutput"><a class="link" href="../boost/proto/result_of/right.html" title="Struct template right">proto::result_of::right<></a></code> + metafunctions that merely forward to their <code class="computeroutput"><a class="link" href="../boost/proto/result_of/child_c.html" title="Struct template child_c">proto::result_of::child_c<></a></code> + counterparts. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.intermediate_form.deep_copying_expressions"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.deep_copying_expressions" title="Deep-copying Expressions">Deep-copying + Expressions</a> +</h4></div></div></div> +<p> + When you build an expression template with Proto, all the intermediate + child nodes are held <span class="emphasis"><em>by reference</em></span>. The avoids needless + copies, which is crucial if you want your EDSL to perform well at runtime. + Naturally, there is a danger if the temporary objects go out of scope before + you try to evaluate your expression template. This is especially a problem + in C++0x with the new <code class="computeroutput"><span class="identifier">decltype</span></code> + and <code class="computeroutput"><span class="keyword">auto</span></code> keywords. Consider: + </p> +<pre class="programlisting"><span class="comment">// OOPS: "ex" is left holding dangling references</span> +<span class="keyword">auto</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">+</span> <span class="number">2</span><span class="special">;</span> +</pre> +<p> + The problem can happen in today's C++ also if you use <code class="computeroutput"><span class="identifier">BOOST_TYPEOF</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">BOOST_AUTO</span><span class="special">()</span></code>, or if you try to pass an expression + template outside the scope of its constituents. + </p> +<p> + In these cases, you want to deep-copy your expression template so that + all intermediate nodes and the terminals are held <span class="emphasis"><em>by value</em></span>. + That way, you can safely assign the expression template to a local variable + or return it from a function without worrying about dangling references. + You can do this with <code class="computeroutput"><a class="link" href="../boost/proto/deep_copy_id1493807.html" title="Function template deep_copy">proto::deep_copy()</a></code> + as fo llows: + </p> +<pre class="programlisting"><span class="comment">// OK, "ex" has no dangling references</span> +<span class="keyword">auto</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">deep_copy</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">+</span> <span class="number">2</span> <span class="special">);</span> +</pre> +<p> + If you are using <a href="../../../libs/typeof/index.html" target="_top">Boost.Typeof</a>, + it would look like this: + </p> +<pre class="programlisting"><span class="comment">// OK, use BOOST_AUTO() and proto::deep_copy() to</span> +<span class="comment">// store an expression template in a local variable </span> +<span class="identifier">BOOST_AUTO</span><span class="special">(</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">deep_copy</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">+</span> <span class="number">2</span> <span class="special">)</span> <span class="special">);</span> +</pre> +<p> + For the above code to work, you must include the <code class="computeroutput"><a class="link" href="reference.html#header.boost.proto.proto_typeof_hpp" title="Header <boost/proto/proto_typeof.hpp>">boost/proto/proto_typeof.hpp</a></code> + header, which also defines the <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_AUTO.html" title="Macro BOOST_PROTO_AUTO">BOOST_PROTO_AUTO</a></code>()</code> + macro which automatically deep-copies its argument. With <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_AUTO.html" title="Macro BOOST_PROTO_AUTO">BOOST_PROTO_AUTO</a></code>()</code>, the above + code can be writen as: + </p> +<pre class="programlisting"><span class="comment">// OK, BOOST_PROTO_AUTO() automatically deep-copies</span> +<span class="comment">// its argument: </span> +<span class="identifier">BOOST_PROTO_AUTO</span><span class="special">(</span> <span class="identifier">ex</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">+</span> <span class="number">2</span> <span class="special">);</span> +</pre> +<p> + When deep-copying an expression tree, all intermediate nodes and all terminals + are stored by value. The only exception is terminals that are function + references, which are left alone. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + <code class="computeroutput"><a class="link" href="../boost/proto/deep_copy_id1493807.html" title="Function template deep_copy">proto::deep_copy()</a></code> makes no exception for + arrays, which it stores by value. That can potentially cause a large + amount of data to be copied. + </p></td></tr> +</table></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.intermediate_form.debugging_expressions"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.debugging_expressions" title="Debugging Expressions">Debugging + Expressions</a> +</h4></div></div></div> +<p> + Proto provides a utility for pretty-printing expression trees that comes + in very handy when you're trying to debug your EDSL. It's called <code class="computeroutput"><a class="link" href="../boost/proto/display_expr_id1492920.html" title="Function display_expr">proto::display_expr()</a></code>, and you pass it the expression + to print and optionally, an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code> + to which to send the output. Consider: + </p> +<pre class="programlisting"><span class="comment">// Use display_expr() to pretty-print an expression tree</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">display_expr</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">+</span> <span class="number">42</span> +<span class="special">);</span> +</pre> +<p> + The above code writes this to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>: + </p> +<pre class="programlisting">plus( + terminal(hello) + , terminal(42) +)</pre> +<p> + In order to call <code class="computeroutput"><a class="link" href="../boost/proto/display_expr_id1492920.html" title="Function display_expr">proto::display_expr()</a></code>, + all the terminals in the expression must be Streamable (that is, they can + be written to a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>). In addition, the tag types + must all be Streamable as well. Here is an example that includes a custom + terminal type and a custom tag: + </p> +<pre class="programlisting"><span class="comment">// A custom tag type that is Streamable</span> +<span class="keyword">struct</span> <span class="identifier">MyTag</span> +<span class="special">{</span> + <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">MyTag</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="string">"MyTag"</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Some other Streamable type</span> +<span class="keyword">struct</span> <span class="identifier">MyTerminal</span> +<span class="special">{</span> + <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">s</span><span class="special">,</span> <span class="identifier">MyTerminal</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="string">"MyTerminal"</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Display an expression tree that contains a custom</span> + <span class="comment">// tag and a user-defined type in a terminal</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">display_expr</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span><span class="identifier">MyTag</span><span class="special">>(</span><span class="identifier">MyTerminal</span><span class="special">())</span> <span class="special">+</span> <span class="number">42</span> + <span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + The above code prints the following: + </p> +<pre class="programlisting">plus( + MyTag( + terminal(MyTerminal) + ) + , terminal(42) +)</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.intermediate_form.tags_and_metafunctions"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.tags_and_metafunctions" title="Operator Tags and Metafunctions">Operator + Tags and Metafunctions</a> +</h4></div></div></div> +<p> + The following table lists the overloadable C++ operators, the Proto tag + types for each, and the name of the metafunctions for generating the corresponding + Proto expression types. And as we'll see later, the metafunctions are also + usable as grammars for matching such nodes, as well as pass-through transforms. + </p> +<div class="table"> +<a name="boost_proto.users_guide.intermediate_form.tags_and_metafunctions.t0"></a><p class="title"><b>Table 20.6. Operators, Tags and Metafunctions</b></p> +<div class="table-contents"><table class="table" summary="Operators, Tags and Metafunctions"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Operator + </p> + </th> +<th> + <p> + Proto Tag + </p> + </th> +<th> + <p> + Proto Metafunction + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + unary <code class="computeroutput"><span class="special">+</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">unary_plus</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_plus</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary <code class="computeroutput"><span class="special">-</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">negate</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">negate</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary <code class="computeroutput"><span class="special">*</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">dereference</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">dereference</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary <code class="computeroutput"><span class="special">~</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">complement</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">complement</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary <code class="computeroutput"><span class="special">&</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">address_of</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">address_of</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary <code class="computeroutput"><span class="special">!</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">logical_not</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_not</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary prefix <code class="computeroutput"><span class="special">++</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">pre_inc</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pre_inc</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary prefix <code class="computeroutput"><span class="special">--</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">pre_dec</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pre_dec</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary postfix <code class="computeroutput"><span class="special">++</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">post_inc</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">post_inc</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + unary postfix <code class="computeroutput"><span class="special">--</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">post_dec</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">post_dec</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special"><<</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_left</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">>></span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_right</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">*</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">multiplies</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">/</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">divides</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">%</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">modulus</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">modulus</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">+</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">-</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">minus</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special"><</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">less</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">less</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">></span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">greater</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">greater</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special"><=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">less_equal</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">less_equal</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">>=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">greater_equal</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">greater_equal</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">==</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">equal_to</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">equal_to</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">!=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">not_equal_to</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_equal_to</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">||</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">logical_or</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_or</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">&&</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">logical_and</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_and</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">&</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_and</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_and</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">|</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_or</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_or</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">^</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_xor</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_xor</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">,</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">comma</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">comma</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">->*</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">mem_ptr</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">mem_ptr</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special"><<=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_left_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">>>=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_right_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">*=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">multiplies_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">/=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">divides_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">%=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">modulus_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">modulus_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">+=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">-=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">minus_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">&=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_and_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_and_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">|=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_or_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_or_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary <code class="computeroutput"><span class="special">^=</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_xor_assign</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_xor_assign</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + binary subscript + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">subscript</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">subscript</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + ternary <code class="computeroutput"><span class="special">?:</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">if_else_</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">if_else_</span><span class="special"><></span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + n-ary function call + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><></span></code> + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expressions_as_fusion_sequences"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expressions_as_fusion_sequences" title="Expressions as Fusion Sequences">Expressions + as Fusion Sequences</a> +</h4></div></div></div> +<p> + Boost.Fusion is a library of iterators, algorithms, containers and adaptors + for manipulating heterogeneous sequences. In essence, a Proto expression + is just a heterogeneous sequence of its child expressions, and so Proto + expressions are valid Fusion random-access sequences. That means you can + apply Fusion algorithms to them, transform them, apply Fusion filters and + views to them, and access their elements using <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">at</span><span class="special">()</span></code>. The things Fusion can do to heterogeneous + sequences are beyond the scope of this users' guide, but below is a simple + example. It takes a lazy function invocation like <code class="computeroutput"><span class="identifier">fun</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">)</span></code> + and uses Fusion to print the function arguments in order. + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">display</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">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">t</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">t</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">struct</span> <span class="identifier">fun_t</span> <span class="special">{};</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">fun_t</span><span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">fun</span> <span class="special">=</span> <span class="special">{{}};</span> + +<span class="comment">// ...</span> +<span class="identifier">fusion</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> + <span class="comment">// pop_front() removes the "fun" child</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">pop_front</span><span class="special">(</span><span class="identifier">fun</span><span class="special">(</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">))</span> + <span class="comment">// Extract the ints from the terminal nodes</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span> + <span class="special">)</span> + <span class="special">,</span> <span class="identifier">display</span><span class="special">()</span> +<span class="special">);</span> +</pre> +<p> + Recall from the Introduction that types in the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span></code> + namespace define function objects that correspond to Proto's free functions. + So <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> + creates a function object that is equivalent to the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> function. The above invocation of <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">()</span></code> + displays the following: + </p> +<pre class="programlisting">1 +2 +3 +4 +</pre> +<p> + Terminals are also valid Fusion sequences. They contain exactly one element: + their value. + </p> +<h6> +<a name="boost_proto.users_guide.intermediate_form.expressions_as_fusion_sequences.h0"></a> + <span><a name="boost_proto.users_guide.intermediate_form.expressions_as_fusion_sequences.flattening_proto_expression_tress"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expressions_as_fusion_sequences.flattening_proto_expression_tress">Flattening + Proto Expression Tress</a> + </h6> +<p> + Imagine a slight variation of the above example where, instead of iterating + over the arguments of a lazy function invocation, we would like to iterate + over the terminals in an addition expression: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">};</span> + +<span class="comment">// ERROR: this doesn't work! Why?</span> +<span class="identifier">fusion</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> + <span class="identifier">_1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">+</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span> + <span class="special">)</span> + <span class="special">,</span> <span class="identifier">display</span><span class="special">()</span> +<span class="special">);</span> +</pre> +<p> + The reason this doesn't work is because the expression <code class="computeroutput"><span class="identifier">_1</span> + <span class="special">+</span> <span class="number">2</span> <span class="special">+</span> <span class="number">3</span> <span class="special">+</span> + <span class="number">4</span></code> does not describe a flat sequence + of terminals --- it describes a binary tree. We can treat it as a flat + sequence of terminals, however, using Proto's <code class="computeroutput"><a class="link" href="../boost/proto/flatten_id1500995.html" title="Function flatten">proto::flatten()</a></code> + function. <code class="computeroutput"><a class="link" href="../boost/proto/flatten_id1500995.html" title="Function flatten">proto::flatten()</a></code> returns a view which makes + a tree appear as a flat Fusion sequence. If the top-most node has a tag + type <code class="computeroutput"><span class="identifier">T</span></code>, then the elements + of the flattened sequence are the child nodes that do <span class="emphasis"><em>not</em></span> + have tag type <code class="computeroutput"><span class="identifier">T</span></code>. This process + is evaluated recursively. So the above can correctly be written as: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">};</span> + +<span class="comment">// OK, iterate over a flattened view</span> +<span class="identifier">fusion</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">flatten</span><span class="special">(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="number">2</span> <span class="special">+</span> <span class="number">3</span> <span class="special">+</span> <span class="number">4</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span> + <span class="special">)</span> + <span class="special">,</span> <span class="identifier">display</span><span class="special">()</span> +<span class="special">);</span> +</pre> +<p> + The above invocation of <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">()</span></code> displays the following: + </p> +<pre class="programlisting">1 +2 +3 +4 +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection" title="Expression Introspection: Defining a Grammar">Expression + Introspection: Defining a Grammar</a> +</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.patterns">Finding + Patterns in Expressions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.fuzzy_and_exact_matches_of_terminals">Fuzzy + and Exact Matches of Terminals</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.if_and_not"><code class="literal">if_<></code>, + <code class="literal">and_<></code>, and <code class="literal">not_<></code></a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.switch">Improving + Compile Times With <code class="literal">switch_<></code></a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.matching_vararg_expressions">Matching + Vararg Expressions</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.defining_edsl_grammars">Defining + EDSL Grammars</a></span></dt> +</dl></div> +<p> + Expression trees can have a very rich and complicated structure. Often, + you need to know some things about an expression's structure before you + can process it. This section describes the tools Proto provides for peering + inside an expression tree and discovering its structure. And as you'll + see in later sections, all the really interesting things you can do with + Proto begin right here. + </p> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.patterns"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.patterns" title="Finding Patterns in Expressions">Finding + Patterns in Expressions</a> +</h5></div></div></div> +<p> + Imagine your EDSL is a miniature I/O facility, with iostream operations + that execute lazily. You might want expressions representing input operations + to be processed by one function, and output operations to be processed + by a different function. How would you do that? + </p> +<p> + The answer is to write patterns (a.k.a, <span class="emphasis"><em>grammars</em></span>) + that match the structure of input and output expressions. Proto provides + utilities for defining the grammars, and the <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a></code> + template for checking whether a given expression type matches the grammar. + </p> +<p> + First, let's define some terminals we can use in our lazy I/O expressions: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cin_</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span> <span class="special">};</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">};</span> +</pre> +<p> + Now, we can use <code class="computeroutput"><span class="identifier">cout_</span></code> + instead of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>, and get I/O expression trees + that we can execute later. To define grammars that match input and output + expressions of the form <code class="computeroutput"><span class="identifier">cin_</span> + <span class="special">>></span> <span class="identifier">i</span></code> + and <code class="computeroutput"><span class="identifier">cout_</span> <span class="special"><<</span> + <span class="number">1</span></code> we do this: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Input</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span> <span class="special">&</span> <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Output</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + We've seen the template <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><></span></code> before, but here we're using + it without accessing the nested <code class="computeroutput"><span class="special">::</span><span class="identifier">type</span></code>. When used like this, it is a + very simple grammar, as are <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><></span></code> and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><></span></code>. The newcomer here is <code class="computeroutput"><span class="identifier">_</span></code> in the <code class="computeroutput"><span class="identifier">proto</span></code> + namespace. It is a wildcard that matches anything. The <code class="computeroutput"><span class="identifier">Input</span></code> struct is a grammar that matches + any right-shift expression that has a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code> + terminal as its left operand. + </p> +<p> + We can use these grammars together with the <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a></code> + template to query at compile time whether a given I/O expression type + is an input or output operation. Consider the following: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">input_output</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="keyword">if</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Input</span> <span class="special">>::</span><span class="identifier">value</span> <span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Input!\n"</span><span class="special">;</span> + <span class="special">}</span> + + <span class="keyword">if</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Output</span> <span class="special">>::</span><span class="identifier">value</span> <span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Output!\n"</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> + <span class="identifier">input_output</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special"><<</span> <span class="number">1</span> <span class="special">);</span> + <span class="identifier">input_output</span><span class="special">(</span> <span class="identifier">cin_</span> <span class="special">>></span> <span class="identifier">i</span> <span class="special">);</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + This program prints the following: + </p> +<pre class="programlisting">Output! +Input! +</pre> +<p> + If we wanted to break the <code class="computeroutput"><span class="identifier">input_output</span><span class="special">()</span></code> function into two functions, one that + handles input expressions and one for output expressions, we can use + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><></span></code>, + as follows: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Input</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">input_output</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Input!\n"</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">Expr</span> <span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Output</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">input_output</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Output!\n"</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + This works as the previous version did. However, the following does not + compile at all: + </p> +<pre class="programlisting"><span class="identifier">input_output</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special"><<</span> <span class="number">1</span> <span class="special"><<</span> <span class="number">2</span> <span class="special">);</span> <span class="comment">// oops!</span> +</pre> +<p> + What's wrong? The problem is that this expression does not match our + grammar. The expression groups as if it were written like <code class="computeroutput"><span class="special">(</span><span class="identifier">cout_</span> <span class="special"><<</span> <span class="number">1</span><span class="special">)</span> <span class="special"><<</span> <span class="number">2</span></code>. It will not match the <code class="computeroutput"><span class="identifier">Output</span></code> grammar, which expects the left + operand to be a terminal, not another left-shift operation. We need to + fix the grammar. + </p> +<p> + We notice that in order to verify an expression as input or output, we'll + need to recurse down to the bottom-left-most leaf and check that it is + a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span></code>. + When we get to the terminal, we must stop recursing. We can express this + in our grammar using <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>. + Here are the correct <code class="computeroutput"><span class="identifier">Input</span></code> + and <code class="computeroutput"><span class="identifier">Output</span></code> grammars: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Input</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">istream</span> <span class="special">&</span> <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><</span> <span class="identifier">Input</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Output</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><</span> <span class="identifier">Output</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + This may look a little odd at first. We seem to be defining the <code class="computeroutput"><span class="identifier">Input</span></code> and <code class="computeroutput"><span class="identifier">Output</span></code> + types in terms of themselves. This is perfectly OK, actually. At the + point in the grammar that the <code class="computeroutput"><span class="identifier">Input</span></code> + and <code class="computeroutput"><span class="identifier">Output</span></code> types are + being used, they are <span class="emphasis"><em>incomplete</em></span>, but by the time + we actually evaluate the grammar with <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a></code>, + the types will be complete. These are recursive grammars, and rightly + so because they must match a recursive data structure! + </p> +<p> + Matching an expression such as <code class="computeroutput"><span class="identifier">cout_</span> + <span class="special"><<</span> <span class="number">1</span> + <span class="special"><<</span> <span class="number">2</span></code> + against the <code class="computeroutput"><span class="identifier">Output</span></code> grammar + procedes as follows: + </p> +<div class="orderedlist"><ol class="orderedlist" type="1"> +<li class="listitem"> + The first alternate of the <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code> + is tried first. It will fail, because the expression <code class="computeroutput"><span class="identifier">cout_</span> <span class="special"><<</span> + <span class="number">1</span> <span class="special"><<</span> + <span class="number">2</span></code> does not match the grammar + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> + <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span></code>. + </li> +<li class="listitem"> + Then the second alternate is tried next. We match the expression + against <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><</span> + <span class="identifier">Output</span><span class="special">,</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span></code>. + The expression is a left-shift, so we next try to match the operands. + </li> +<li class="listitem"> + The right operand <code class="computeroutput"><span class="number">2</span></code> matches + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> trivially. + </li> +<li class="listitem"> + To see if the left operand <code class="computeroutput"><span class="identifier">cout_</span> + <span class="special"><<</span> <span class="number">1</span></code> + matches <code class="computeroutput"><span class="identifier">Output</span></code>, we + must recursively evaluate the <code class="computeroutput"><span class="identifier">Output</span></code> + grammar. This time we succeed, because <code class="computeroutput"><span class="identifier">cout_</span> + <span class="special"><<</span> <span class="number">1</span></code> + will match the first alternate of the <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>. + </li> +</ol></div> +<p> + We're done -- the grammar matches successfully. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.fuzzy_and_exact_matches_of_terminals"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.fuzzy_and_exact_matches_of_terminals" title="Fuzzy and Exact Matches of Terminals">Fuzzy + and Exact Matches of Terminals</a> +</h5></div></div></div> +<p> + The terminals in an expression tree could be const or non-const references, + or they might not be references at all. When writing grammars, you usually + don't have to worry about it because <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a></code> + gives you a little wiggle room when matching terminals. A grammar such + as <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> + will match a terminal of type <code class="computeroutput"><span class="keyword">int</span></code>, + <code class="computeroutput"><span class="keyword">int</span> <span class="special">&</span></code>, + or <code class="computeroutput"><span class="keyword">int</span> <span class="keyword">const</span> + <span class="special">&</span></code>. + </p> +<p> + You can explicitly specify that you want to match a reference type. If + you do, the type must match exactly. For instance, a grammar such as + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span> <span class="special">&></span></code> + will only match an <code class="computeroutput"><span class="keyword">int</span> <span class="special">&</span></code>. It will not match an <code class="computeroutput"><span class="keyword">int</span></code> or an <code class="computeroutput"><span class="keyword">int</span> + <span class="keyword">const</span> <span class="special">&</span></code>. + </p> +<p> + The table below shows how Proto matches terminals. The simple rule is: + if you want to match only reference types, you must specify the reference + in your grammar. Otherwise, leave it off and Proto will ignore const + and references. + </p> +<div class="table"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.fuzzy_and_exact_matches_of_terminals.t0"></a><p class="title"><b>Table 20.7. proto::matches<> and Reference / CV-Qualification of Terminals</b></p> +<div class="table-contents"><table class="table" summary="proto::matches<> and Reference / CV-Qualification of Terminals"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Terminal + </p> + </th> +<th> + <p> + Grammar + </p> + </th> +<th> + <p> + Matches? + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + T + </p> + </td> +<td> + <p> + T + </p> + </td> +<td> + <p> + yes + </p> + </td> +</tr> +<tr> +<td> + <p> + T & + </p> + </td> +<td> + <p> + T + </p> + </td> +<td> + <p> + yes + </p> + </td> +</tr> +<tr> +<td> + <p> + T const & + </p> + </td> +<td> + <p> + T + </p> + </td> +<td> + <p> + yes + </p> + </td> +</tr> +<tr> +<td> + <p> + T + </p> + </td> +<td> + <p> + T & + </p> + </td> +<td> + <p> + no + </p> + </td> +</tr> +<tr> +<td> + <p> + T & + </p> + </td> +<td> + <p> + T & + </p> + </td> +<td> + <p> + yes + </p> + </td> +</tr> +<tr> +<td> + <p> + T const & + </p> + </td> +<td> + <p> + T & + </p> + </td> +<td> + <p> + no + </p> + </td> +</tr> +<tr> +<td> + <p> + T + </p> + </td> +<td> + <p> + T const & + </p> + </td> +<td> + <p> + no + </p> + </td> +</tr> +<tr> +<td> + <p> + T & + </p> + </td> +<td> + <p> + T const & + </p> + </td> +<td> + <p> + no + </p> + </td> +</tr> +<tr> +<td> + <p> + T const & + </p> + </td> +<td> + <p> + T const & + </p> + </td> +<td> + <p> + yes + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><p> + This begs the question: What if you want to match an <code class="computeroutput"><span class="keyword">int</span></code>, + but not an <code class="computeroutput"><span class="keyword">int</span> <span class="special">&</span></code> + or an <code class="computeroutput"><span class="keyword">int</span> <span class="keyword">const</span> + <span class="special">&</span></code>? For forcing exact matches, + Proto provides the <code class="computeroutput"><a class="link" href="../boost/proto/exact.html" title="Struct template exact">proto::exact<></a></code> + template. For instance, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">exact</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">></span></code> + would only match an <code class="computeroutput"><span class="keyword">int</span></code> + held by value. + </p> +<p> + Proto gives you extra wiggle room when matching array types. Array types + match themselves or the pointer types they decay to. This is especially + useful with character arrays. The type returned by <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="string">"hello"</span><span class="special">)</span></code> is <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">[</span><span class="number">6</span><span class="special">]>::</span><span class="identifier">type</span></code>. That's a terminal containing + a 6-element character array. Naturally, you can match this terminal with + the grammar <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">[</span><span class="number">6</span><span class="special">]></span></code>, + but the grammar <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*></span></code> + will match it as well, as the following code fragment illustrates. + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">CharString</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">[</span><span class="number">6</span><span class="special">]</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">char_array</span><span class="special">;</span> + +<span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">char_array</span><span class="special">,</span> <span class="identifier">CharString</span> <span class="special">></span> <span class="special">));</span> +</pre> +<p> + What if we only wanted <code class="computeroutput"><span class="identifier">CharString</span></code> + to match terminals of exactly the type <code class="computeroutput"><span class="keyword">char</span> + <span class="keyword">const</span> <span class="special">*</span></code>? + You can use <code class="computeroutput"><a class="link" href="../boost/proto/exact.html" title="Struct template exact">proto::exact<></a></code> here to turn off + the fuzzy matching of terminals, as follows: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">CharString</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">exact</span><span class="special"><</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="special">></span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">[</span><span class="number">6</span><span class="special">]>::</span><span class="identifier">type</span> <span class="identifier">char_array</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*>::</span><span class="identifier">type</span> <span class="identifier">char_string</span><span class="special">;</span> + +<span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">char_string</span><span class="special">,</span> <span class="identifier">CharString</span> <span class="special">></span> <span class="special">));</span> +<span class="identifier">BOOST_MPL_ASSERT_NOT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">char_array</span><span class="special">,</span> <span class="identifier">CharString</span> <span class="special">></span> <span class="special">));</span> +</pre> +<p> + Now, <code class="computeroutput"><span class="identifier">CharString</span></code> does + not match array types, only character string pointers. + </p> +<p> + The inverse problem is a little trickier: what if you wanted to match + all character arrays, but not character pointers? As mentioned above, + the expression <code class="computeroutput"><span class="identifier">as_expr</span><span class="special">(</span><span class="string">"hello"</span><span class="special">)</span></code> has the type <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">[</span> <span class="number">6</span> <span class="special">]</span> <span class="special">>::</span><span class="identifier">type</span></code>. If you wanted to match character + arrays of arbitrary size, you could use <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">N</span></code>, + which is an array-size wildcard. The following grammar would match any + string literal: <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">char</span> <span class="keyword">const</span><span class="special">[</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">N</span> <span class="special">]</span> <span class="special">></span></code>. + </p> +<p> + Sometimes you need even more wiggle room when matching terminals. For + example, maybe you're building a calculator EDSL and you want to allow + any terminals that are convertible to <code class="computeroutput"><span class="keyword">double</span></code>. + For that, Proto provides the <code class="computeroutput"><a class="link" href="../boost/proto/convertible_to.html" title="Struct template convertible_to">proto::convertible_to<></a></code> + template. You can use it as: <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">convertible_to</span><span class="special"><</span> <span class="keyword">double</span> + <span class="special">></span> <span class="special">></span></code>. + </p> +<p> + There is one more way you can perform a fuzzy match on terminals. Consider + the problem of trying to match a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><></span></code> terminal. You can easily match + a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">float</span><span class="special">></span></code> + or a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span></code>, + but how would you match any instantiation of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><></span></code>? You can use <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> + here to solve this problem. Here is the grammar to match any <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><></span></code> + instantiation: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">StdComplex</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + When given a grammar like this, Proto will deconstruct the grammar and + the terminal it is being matched against and see if it can match all + the constituents. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.if_and_not"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.if_and_not" title="if_<>, and_<>, and not_<>"><code class="literal">if_<></code>, + <code class="literal">and_<></code>, and <code class="literal">not_<></code></a> +</h5></div></div></div> +<p> + We've already seen how to use expression generators like <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><></span></code> + and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><></span></code> + as grammars. We've also seen <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>, + which we can use to express a set of alternate grammars. There are a + few others of interest; in particular, <code class="computeroutput"><a class="link" href="../boost/proto/if_.html" title="Struct template if_">proto::if_<></a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_<></a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/not_.html" title="Struct template not_">proto::not_<></a></code>. + </p> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/not_.html" title="Struct template not_">proto::not_<></a></code> template is the simplest. + It takes a grammar as a template parameter and logically negates it; + <code class="computeroutput"><span class="identifier">not_</span><span class="special"><</span><span class="identifier">Grammar</span><span class="special">></span></code> + will match any expression that <code class="computeroutput"><span class="identifier">Grammar</span></code> + does <span class="emphasis"><em>not</em></span> match. + </p> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/if_.html" title="Struct template if_">proto::if_<></a></code> template is used + together with a Proto transform that is evaluated against expression + types to find matches. (Proto transforms will be described later.) + </p> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_<></a></code> template is like + <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>, except that each + argument of the <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_<></a></code> must match in order + for the <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_<></a></code> to match. As an example, + consider the definition of <code class="computeroutput"><span class="identifier">CharString</span></code> + above that uses <code class="computeroutput"><a class="link" href="../boost/proto/exact.html" title="Struct template exact">proto::exact<></a></code>. It could have been + written without <code class="computeroutput"><a class="link" href="../boost/proto/exact.html" title="Struct template exact">proto::exact<></a></code> as follows: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">CharString</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">and_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">if_</span><span class="special"><</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="special">>()</span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + This says that a <code class="computeroutput"><span class="identifier">CharString</span></code> + must be a terminal, <span class="emphasis"><em>and</em></span> its value type must be the + same as <code class="computeroutput"><span class="keyword">char</span> <span class="keyword">const</span> + <span class="special">*</span></code>. Notice the template argument + of <code class="computeroutput"><a class="link" href="../boost/proto/if_.html" title="Struct template if_">proto::if_<></a></code>: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">,</span> <span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span> <span class="special">>()</span></code>. This is Proto transform that compares + the value type of a terminal to <code class="computeroutput"><span class="keyword">char</span> + <span class="keyword">const</span> <span class="special">*</span></code>. + </p> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/if_.html" title="Struct template if_">proto::if_<></a></code> template has a couple + of variants. In addition to <code class="computeroutput"><span class="identifier">if_</span><span class="special"><</span><span class="identifier">Condition</span><span class="special">></span></code> you can also say <code class="computeroutput"><span class="identifier">if_</span><span class="special"><</span><span class="identifier">Condition</span><span class="special">,</span> <span class="identifier">ThenGrammar</span><span class="special">></span></code> and <code class="computeroutput"><span class="identifier">if_</span><span class="special"><</span><span class="identifier">Condition</span><span class="special">,</span> <span class="identifier">ThenGrammar</span><span class="special">,</span> <span class="identifier">ElseGrammar</span><span class="special">></span></code>. These let you select one sub-grammar + or another based on the <code class="computeroutput"><span class="identifier">Condition</span></code>. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.switch"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.switch" title="Improving Compile Times With switch_<>">Improving + Compile Times With <code class="literal">switch_<></code></a> +</h5></div></div></div> +<p> + When your Proto grammar gets large, you'll start to run into some scalability + problems with <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>, the construct you + use to specify alternate sub-grammars. First, due to limitations in C++, + <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code> can only accept up + to a certain number of sub-grammars, controlled by the <code class="computeroutput"><span class="identifier">BOOST_PROTO_MAX_LOGICAL_ARITY</span></code> macro. + This macro defaults to eight, and you can set it higher, but doing so + will aggravate another scalability problem: long compile times. With + <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>, alternate sub-grammars + are tried in order -- like a series of cascading <code class="computeroutput"><span class="keyword">if</span></code>'s + -- leading to lots of unnecessary template instantiations. What you would + prefer instead is something like <code class="computeroutput"><span class="keyword">switch</span></code> + that avoids the expense of cascading <code class="computeroutput"><span class="keyword">if</span></code>'s. + That's the purpose of <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code>; + although less convenient than <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>, + it improves compile times for larger grammars and does not have an arbitrary + fixed limit on the number of sub-grammars. + </p> +<p> + Let's illustrate how to use <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code> + by first writing a big grammar with <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code> + and then translating it to an equivalent grammar using <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code>: + </p> +<pre class="programlisting"><span class="comment">// Here is a big, inefficient grammar</span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_plus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">negate</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">complement</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">modulus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The above might be the grammar to a more elaborate calculator EDSL. Notice + that since there are more than eight sub-grammars, we had to chain the + sub-grammars with a nested <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code> + -- not very nice. + </p> +<p> + The idea behind <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code> + is to dispatch based on an expression's tag type to a sub-grammar that + handles expressions of that type. To use <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code>, + you define a struct with a nested <code class="computeroutput"><span class="identifier">case_</span><span class="special"><></span></code> template, specialized on tag + types. The above grammar can be expressed using <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code> + as follows. It is described below. + </p> +<pre class="programlisting"><span class="comment">// Redefine ABigGrammar more efficiently using proto::switch_<></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammar</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span> +<span class="special">{</span> + <span class="comment">// The primary template matches nothing:</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">case_</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">{};</span> +<span class="special">};</span> + +<span class="comment">// Terminal expressions are handled here</span> +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Non-terminals are handled similarly</span> +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">unary_plus</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_plus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">negate</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">negate</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">complement</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">complement</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">minus</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">divides</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">modulus</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">modulus</span><span class="special"><</span><span class="identifier">ABigGrammar</span><span class="special">,</span> <span class="identifier">ABigGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Define ABigGrammar in terms of ABigGrammarCases</span> +<span class="comment">// using proto::switch_<></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">switch_</span><span class="special"><</span><span class="identifier">ABigGrammarCases</span><span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Matching an expression type <code class="computeroutput"><span class="identifier">E</span></code> + against <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">switch_</span><span class="special"><</span><span class="identifier">C</span><span class="special">></span></code> + is equivalent to matching it against <code class="computeroutput"><span class="identifier">C</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">E</span><span class="special">::</span><span class="identifier">proto_tag</span><span class="special">></span></code>. By dispatching on the expression's + tag type, we can jump to the sub-grammar that handles expressions of + that type, skipping over all the other sub-grammars that couldn't possibly + match. If there is no specialization of <code class="computeroutput"><span class="identifier">case_</span><span class="special"><></span></code> for a particular tag type, we + select the primary template. In this case, the primary template inherits + from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span></code> + which matches no expressions. + </p> +<p> + Notice the specialization that handles terminals: + </p> +<pre class="programlisting"><span class="comment">// Terminal expressions are handled here</span> +<span class="keyword">template</span><span class="special"><></span> +<span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span><span class="special">::</span><span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span></code> type by itself isn't enough + to select an appropriate sub-grammar, so we use <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code> + to list the alternate sub-grammars that match terminals. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + You might be tempted to define your <code class="computeroutput"><span class="identifier">case_</span><span class="special"><></span></code> specializations <span class="emphasis"><em>in + situ</em></span> as follows: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">case_</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">{};</span> + + <span class="comment">// ERROR: not legal C++</span> + <span class="keyword">template</span><span class="special"><></span> + <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">></span> + <span class="comment">/* ... */</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + Unfortunately, for arcane reasons, it is not legal to define an explicit + nested specialization <span class="emphasis"><em>in situ</em></span> like this. It is, + however, perfectly legal to define <span class="emphasis"><em>partial</em></span> specializations + <span class="emphasis"><em>in situ</em></span>, so you can add a extra dummy template + parameter that has a default, as follows: + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">ABigGrammarCases</span> +<span class="special">{</span> + <span class="comment">// Note extra "Dummy" template parameter here:</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">Dummy</span> <span class="special">=</span> <span class="number">0</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">case_</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">{};</span> + + <span class="comment">// OK: "Dummy" makes this a partial specialization</span> + <span class="comment">// instead of an explicit specialization.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">Dummy</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">Dummy</span><span class="special">></span> + <span class="comment">/* ... */</span> +<span class="special">};</span> +</pre> +<p> + </p> +<p> + You might find this cleaner than defining explicit <code class="computeroutput"><span class="identifier">case_</span><span class="special"><></span></code> specializations outside of + their enclosing struct. + </p> +</td></tr> +</table></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.matching_vararg_expressions"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.matching_vararg_expressions" title="Matching Vararg Expressions">Matching + Vararg Expressions</a> +</h5></div></div></div> +<p> + Not all of C++'s overloadable operators are unary or binary. There is + the oddball <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> + -- the function call operator -- which can have any number of arguments. + Likewise, with Proto you may define your own "operators" that + could also take more that two arguments. As a result, there may be nodes + in your Proto expression tree that have an arbitrary number of children + (up to <code class="literal"><code class="computeroutput"><a class="link" href="../BOOST_PROTO_MAX_ARITY.html" title="Macro BOOST_PROTO_MAX_ARITY">BOOST_PROTO_MAX_ARITY</a></code></code>, + which is configurable). How do you write a grammar to match such a node? + </p> +<p> + For such cases, Proto provides the <code class="computeroutput"><a class="link" href="../boost/proto/vararg.html" title="Struct template vararg">proto::vararg<></a></code> + class template. Its template argument is a grammar, and the <code class="computeroutput"><a class="link" href="../boost/proto/vararg.html" title="Struct template vararg">proto::vararg<></a></code> will match the grammar + zero or more times. Consider a Proto lazy function called <code class="computeroutput"><span class="identifier">fun</span><span class="special">()</span></code> + that can take zero or more characters as arguments, as follows: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">fun_tag</span> <span class="special">{};</span> +<span class="keyword">struct</span> <span class="identifier">FunTag</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">fun_tag</span> <span class="special">></span> <span class="special">{};</span> +<span class="identifier">FunTag</span><span class="special">::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">fun</span> <span class="special">=</span> <span class="special">{{}};</span> + +<span class="comment">// example usage:</span> +<span class="identifier">fun</span><span class="special">();</span> +<span class="identifier">fun</span><span class="special">(</span><span class="char">'a'</span><span class="special">);</span> +<span class="identifier">fun</span><span class="special">(</span><span class="char">'a'</span><span class="special">,</span> <span class="char">'b'</span><span class="special">);</span> +<span class="special">...</span> +</pre> +<p> + Below is the grammar that matches all the allowable invocations of <code class="computeroutput"><span class="identifier">fun</span><span class="special">()</span></code>: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">FunCall</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> <span class="identifier">FunTag</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">char</span> <span class="special">></span> <span class="special">></span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The <code class="computeroutput"><span class="identifier">FunCall</span></code> grammar uses + <code class="computeroutput"><a class="link" href="../boost/proto/vararg.html" title="Struct template vararg">proto::vararg<></a></code> to match zero or + more character literals as arguments of the <code class="computeroutput"><span class="identifier">fun</span><span class="special">()</span></code> function. + </p> +<p> + As another example, can you guess what the following grammar matches? + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Foo</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span> <span class="identifier">Foo</span> <span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Here's a hint: the first template parameter to <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><></span></code> represents the node type, and + any additional template parameters represent child nodes. The answer + is that this is a degenerate grammar that matches every possible expression + tree, from root to leaves. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.intermediate_form.expression_introspection.defining_edsl_grammars"></a><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form.expression_introspection.defining_edsl_grammars" title="Defining EDSL Grammars">Defining + EDSL Grammars</a> +</h5></div></div></div> +<p> + In this section we'll see how to use Proto to define a grammar for your + EDSL and use it to validate expression templates, giving short, readable + compile-time errors for invalid expressions. + </p> +<div class="tip"><table border="0" summary="Tip"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td> +<th align="left">Tip</th> +</tr> +<tr><td align="left" valign="top"> +<p> + You might think that this is a backwards way of doing things. <span class="quote">“<span class="quote">If + Proto let me select which operators to overload, my users wouldn't + be able to create invalid expressions in the first place, and I wouldn't + need a grammar at all!</span>”</span> That may be true, but there are reasons + for preferring to do things this way. + </p> +<p> + First, it lets you develop your EDSL rapidly -- all the operators are + there for you already! -- and worry about invalid syntax later. + </p> +<p> + Second, it might be the case that some operators are only allowed in + certain contexts within your EDSL. This is easy to express with a grammar, + and hard to do with straight operator overloading. + </p> +<p> + Third, using a EDSL grammar to flag invalid expressions can often yield + better errors than manually selecting the overloaded operators. + </p> +<p> + Fourth, the grammar can be used for more than just validation. You + can use your grammar to define <span class="emphasis"><em>tree transformations</em></span> + that convert expression templates into other more useful objects. + </p> +<p> + If none of the above convinces you, you actually <span class="emphasis"><em>can</em></span> + use Proto to control which operators are overloaded within your domain. + And to do it, you need to define a grammar! + </p> +</td></tr> +</table></div> +<p> + In a previous section, we used Proto to define a EDSL for a lazily evaluated + calculator that allowed any combination of placeholders, floating-point + literals, addition, subtraction, multiplication, division and grouping. + If we were to write the grammar for this EDSL in <a href="http://en.wikipedia.org/wiki/Extended_Backus_Naur_Form" target="_top">EBNF</a>, + it might look like this: + </p> +<pre class="programlisting">group ::= '(' expression ')' +factor ::= double | '_1' | '_2' | group +term ::= factor (('*' factor) | ('/' factor))* +expression ::= term (('+' term) | ('-' term))* +</pre> +<p> + This captures the syntax, associativity and precedence rules of a calculator. + Writing the grammar for our calculator EDSL using Proto is <span class="emphasis"><em>even + simpler</em></span>. Since we are using C++ as the host language, we are + bound to the associativity and precedence rules for the C++ operators. + Our grammar can assume them. Also, in C++ grouping is already handled + for us with the use of parenthesis, so we don't have to code that into + our grammar. + </p> +<p> + Let's begin our grammar for forward-declaring it: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">CalculatorGrammar</span><span class="special">;</span> +</pre> +<p> + It's an incomplete type at this point, but we'll still be able to use + it to define the rules of our grammar. Let's define grammar rules for + the terminals: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Double</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">convertible_to</span><span class="special"><</span> <span class="keyword">double</span> <span class="special">></span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Placeholder1</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</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">struct</span> <span class="identifier">Placeholder2</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</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">struct</span> <span class="identifier">Terminal</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> <span class="identifier">Double</span><span class="special">,</span> <span class="identifier">Placeholder1</span><span class="special">,</span> <span class="identifier">Placeholder2</span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Now let's define the rules for addition, subtraction, multiplication + and division. Here, we can ignore issues of associativity and precedence + -- the C++ compiler will enforce that for us. We only must enforce that + the arguments to the operators must themselves conform to the <code class="computeroutput"><span class="identifier">CalculatorGrammar</span></code> that we forward-declared + above. + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Plus</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span> <span class="identifier">CalculatorGrammar</span><span class="special">,</span> <span class="identifier">CalculatorGrammar</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Minus</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span> <span class="identifier">CalculatorGrammar</span><span class="special">,</span> <span class="identifier">CalculatorGrammar</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Multiplies</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span> <span class="identifier">CalculatorGrammar</span><span class="special">,</span> <span class="identifier">CalculatorGrammar</span> <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Divides</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span> <span class="identifier">CalculatorGrammar</span><span class="special">,</span> <span class="identifier">CalculatorGrammar</span> <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Now that we've defined all the parts of the grammar, we can define <code class="computeroutput"><span class="identifier">CalculatorGrammar</span></code>: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">CalculatorGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">Terminal</span> + <span class="special">,</span> <span class="identifier">Plus</span> + <span class="special">,</span> <span class="identifier">Minus</span> + <span class="special">,</span> <span class="identifier">Multiplies</span> + <span class="special">,</span> <span class="identifier">Divides</span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + That's it! Now we can use <code class="computeroutput"><span class="identifier">CalculatorGrammar</span></code> + to enforce that an expression template conforms to our grammar. We can + use <code class="computeroutput"><a class="link" href="../boost/proto/matches.html" title="Struct template matches">proto::matches<></a></code> and <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span><span class="special">()</span></code> + to issue readable compile-time errors for invalid expressions, as below: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">CalculatorGrammar</span> <span class="special">></span> <span class="special">));</span> + <span class="comment">// ...</span> +<span class="special">}</span> +</pre> +</div> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.back_end"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end" title="Back Ends: Making Expression Templates Do Useful Work">Back Ends: Making Expression + Templates Do Useful Work</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation">Expression + Evaluation: Imparting Behaviors with a Context</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation">Expression + Transformation: Semantic Actions</a></span></dt> +</dl></div> +<p> + Now that you've written the front end for your EDSL compiler, and you've + learned a bit about the intermediate form it produces, it's time to think + about what to <span class="emphasis"><em>do</em></span> with the intermediate form. This is + where you put your domain-specific algorithms and optimizations. Proto gives + you two ways to evaluate and manipulate expression templates: contexts and + transforms. + </p> +<div class="itemizedlist"><ul class="itemizedlist" type="disc"> +<li class="listitem"> + A <span class="emphasis"><em>context</em></span> is like a function object that you pass + along with an expression to the <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + function. It associates behaviors with node types. <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + walks the expression and invokes your context at each node. + </li> +<li class="listitem"> + A <span class="emphasis"><em>transform</em></span> is a way to associate behaviors, not + with node types in an expression, but with rules in a Proto grammar. + In this way, they are like semantic actions in other compiler-construction + toolkits. + </li> +</ul></div> +<p> + Two ways to evaluate expressions! How to choose? Since contexts are largely + procedural, they are a bit simpler to understand and debug so they are a + good place to start. But although transforms are more advanced, they are + also more powerful; since they are associated with rules in your grammar, + you can select the proper transform based on the entire <span class="emphasis"><em>structure</em></span> + of a sub-expression rather than simply on the type of its top-most node. + </p> +<p> + Also, transforms have a concise and declarative syntax that can be confusing + at first, but highly expressive and fungible once you become accustomed to + it. And -- this is admittedly very subjective -- the author finds programming + with Proto transforms to be an inordinate amount of <span class="emphasis"><em>fun!</em></span> + Your mileage may vary. + </p> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation" title="Expression Evaluation: Imparting Behaviors with a Context">Expression + Evaluation: Imparting Behaviors with a Context</a> +</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.proto_eval">Evaluating + an Expression with <code class="literal">proto::eval()</code></a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.contexts">Defining + an Evaluation Context</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts">Proto's + Built-In Contexts</a></span></dt> +</dl></div> +<p> + Once you have constructed a Proto expression tree, either by using Proto's + operator overloads or with <code class="computeroutput"><a class="link" href="../boost/proto/make_expr_id1503817.html" title="Function make_expr">proto::make_expr()</a></code> + and friends, you probably want to actually <span class="emphasis"><em>do</em></span> something + with it. The simplest option is to use <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code>, a generic expression evaluator. To use + <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code>, you'll need to define + a <span class="emphasis"><em>context</em></span> that tells <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + how each node should be evaluated. This section goes through the nuts and + bolts of using <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code>, defining evaluation contexts, + and using the contexts that Proto provides. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code> + is a less powerful but easier-to-use evaluation technique than Proto + transforms, which are covered later. Although very powerful, transforms + have a steep learning curve and can be more difficult to debug. <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code> + is a rather weak tree traversal algorithm. Dan Marsden has been working + on a more general and powerful tree traversal library. When it is ready, + I anticipate that it will eliminate the need for <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code>. + </p></td></tr> +</table></div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation.proto_eval"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.proto_eval" title="Evaluating an Expression with proto::eval()">Evaluating + an Expression with <code class="literal">proto::eval()</code></a> +</h5></div></div></div> +<div class="blockquote"><blockquote class="blockquote"><p> + <span class="bold"><strong>Synopsis:</strong></span> + </p></blockquote></div> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">proto</span> +<span class="special">{</span> + <span class="keyword">namespace</span> <span class="identifier">result_of</span> + <span class="special">{</span> + <span class="comment">// A metafunction for calculating the return</span> + <span class="comment">// type of proto::eval() given certain Expr</span> + <span class="comment">// and Context types.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">{</span> + <span class="keyword">typedef</span> + <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">result_type</span> + <span class="identifier">type</span><span class="special">;</span> + <span class="special">};</span> + <span class="special">}</span> + + <span class="keyword">namespace</span> <span class="identifier">functional</span> + <span class="special">{</span> + <span class="comment">// A callable function object type for evaluating</span> + <span class="comment">// a Proto expression with a certain context.</span> + <span class="keyword">struct</span> <span class="identifier">eval</span> <span class="special">:</span> <span class="identifier">callable</span> + <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Sig</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span><span class="special">>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">&</span><span class="identifier">context</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span><span class="special">>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">context</span><span class="special">)</span> <span class="keyword">const</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">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span><span class="special">>::</span><span class="identifier">type</span> + <span class="identifier">eval</span><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">&</span><span class="identifier">context</span><span class="special">);</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span><span class="special">>::</span><span class="identifier">type</span> + <span class="identifier">eval</span><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">context</span><span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + Given an expression and an evaluation context, using <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> + is quite simple. Simply pass the expression and the context to <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> and it does the rest + and returns the result. You can use the <code class="computeroutput"><span class="identifier">eval</span><span class="special"><></span></code> metafunction in the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span></code> namespace to compute the + return type of <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code>. The following demonstrates + a use of <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code>: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">MyContext</span><span class="special">>::</span><span class="identifier">type</span> +<span class="identifier">MyEvaluate</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> +<span class="special">{</span> + <span class="comment">// Some user-defined context type</span> + <span class="identifier">MyContext</span> <span class="identifier">ctx</span><span class="special">;</span> + + <span class="comment">// Evaluate an expression with the context</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + What <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> does is also very simple. + It defers most of the work to the context itself. Here essentially is + the implementation of <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code>: + </p> +<pre class="programlisting"><span class="comment">// eval() dispatches to a nested "eval<>" function</span> +<span class="comment">// object within the Context:</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> +<span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">result_type</span> +<span class="identifier">eval</span><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">></span> <span class="identifier">eval_fun</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">eval_fun</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + Really, <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> is nothing more than + a thin wrapper that dispatches to the appropriate handler within the + context class. In the next section, we'll see how to implement a context + class from scratch. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation.contexts"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.contexts" title="Defining an Evaluation Context">Defining + an Evaluation Context</a> +</h5></div></div></div> +<p> + As we saw in the previous section, there is really not much to the <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> function. Rather, all + the interesting expression evaluation goes on within a context class. + This section shows how to implement one from scratch. + </p> +<p> + All context classes have roughly the following form: + </p> +<pre class="programlisting"><span class="comment">// A prototypical user-defined context.</span> +<span class="keyword">struct</span> <span class="identifier">MyContext</span> +<span class="special">{</span> + <span class="comment">// A nested eval<> class template</span> + <span class="keyword">template</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">Expr</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag_of</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span> + <span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special">;</span> + + <span class="comment">// Handle terminal nodes here...</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">></span> + <span class="special">{</span> + <span class="comment">// Must have a nested result_type typedef.</span> + <span class="keyword">typedef</span> <span class="special">...</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Must have a function call operator that takes</span> + <span class="comment">// an expression and the context.</span> + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">MyContext</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="special">...;</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="comment">// ... other specializations of struct eval<> ...</span> +<span class="special">};</span> +</pre> +<p> + Context classes are nothing more than a collection of specializations + of a nested <code class="computeroutput"><span class="identifier">eval</span><span class="special"><></span></code> + class template. Each specialization handles a different expression type. + </p> +<p> + In the <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">Hello + Calculator</a> section, we saw an example of a user-defined context + class for evaluating calculator expressions. That context class was implemented + with the help of Proto's <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code>. + If we were to implement it from scratch, it would look something like + this: + </p> +<pre class="programlisting"><span class="comment">// The calculator_context from the "Hello Calculator" section,</span> +<span class="comment">// implemented from scratch.</span> +<span class="keyword">struct</span> <span class="identifier">calculator_context</span> +<span class="special">{</span> + <span class="comment">// The values with which we'll replace the placeholders</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">args</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">Expr</span> + <span class="comment">// defaulted template parameters, so we can</span> + <span class="comment">// specialize on the expressions that need</span> + <span class="comment">// special handling.</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag_of</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg0</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">Expr</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">struct</span> <span class="identifier">eval</span><span class="special">;</span> + + <span class="comment">// Handle placeholder terminals here...</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">></span> <span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&,</span> <span class="identifier">MyContext</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">[</span><span class="identifier">I</span><span class="special">];</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="comment">// Handle other terminals here...</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg0</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">Arg0</span><span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">MyContext</span> <span class="special">&)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">child</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="comment">// Handle addition here...</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg0</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">Arg0</span><span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">MyContext</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">left</span><span class="special">(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">ctx</span><span class="special">)</span> + <span class="special">+</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="comment">// ... other eval<> specializations for other node types ...</span> +<span class="special">};</span> +</pre> +<p> + Now we can use <code class="computeroutput"><a class="link" href="../boost/proto/eval_id1495281.html" title="Function eval">proto::eval()</a></code> with the context class + above to evaluate calculator expressions as follows: + </p> +<pre class="programlisting"><span class="comment">// Evaluate an expression with a calculator_context</span> +<span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">5</span><span class="special">);</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">6</span><span class="special">);</span> +<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="identifier">_2</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="identifier">assert</span><span class="special">(</span><span class="number">11</span> <span class="special">==</span> <span class="identifier">d</span><span class="special">);</span> +</pre> +<p> + Defining a context from scratch this way is tedious and verbose, but + it gives you complete control over how the expression is evaluated. The + context class in the <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">Hello + Calculator</a> example was much simpler. In the next section we'll + see the helper class Proto provides to ease the job of implementing context + classes. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation.canned_contexts"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts" title="Proto's Built-In Contexts">Proto's + Built-In Contexts</a> +</h5></div></div></div> +<p> + Proto provides some ready-made context classes that you can use as-is, + or that you can use to help while implementing your own contexts. They + are: + </p> +<div class="variablelist"> +<p class="title"><b></b></p> +<dl> +<dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.default_context" title="default_context"><code class="literal">default_context</code></a></span></dt> +<dd><p> + An evaluation context that assigns the usual C++ meanings to all + the operators. For example, addition nodes are handled by evaluating + the left and right children and then adding the results. The <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code> + uses Boost.Typeof to deduce the types of the expressions it evaluates. + </p></dd> +<dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.null_context" title="null_context"><code class="literal">null_context</code></a></span></dt> +<dd><p> + A simple context that recursively evaluates children but does not + combine the results in any way and returns void. + </p></dd> +<dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.callable_context" title="callable_context<>"><code class="literal">callable_context<></code></a></span></dt> +<dd><p> + A helper that simplifies the job of writing context classes. Rather + than writing template specializations, with <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + you write a function object with an overloaded function call operator. + Any expressions not handled by an overload are automatically dispatched + to a default evaluation context that you can specify. + </p></dd> +</dl> +</div> +<div class="section"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.default_context"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.default_context" title="default_context"><code class="literal">default_context</code></a> +</h6></div></div></div> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code> is an + evaluation context that assigns the usual C++ meanings to all the operators. + For example, addition nodes are handled by evaluating the left and + right children and then adding the results. The <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code> uses + Boost.Typeof to deduce the types of the expressions it evaluates. + </p> +<p> + For example, consider the following "Hello World" example: + </p> +<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">proto</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">proto</span><span class="special">/</span><span class="identifier">context</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">;</span> + +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">};</span> + +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="comment">// Evaluate the expression with default_context,</span> + <span class="comment">// to give the operators their C++ meanings:</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special"><<</span> <span class="string">"hello"</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="string">" world"</span> <span class="special">);</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + This program outputs the following: + </p> +<pre class="programlisting">hello, world +</pre> +<p> + <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code> is trivially + defined in terms of a <code class="computeroutput"><span class="identifier">default_eval</span><span class="special"><></span></code> template, as follows: + </p> +<pre class="programlisting"><span class="comment">// Definition of default_context</span> +<span class="keyword">struct</span> <span class="identifier">default_context</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">default_eval</span><span class="special"><</span> + <span class="identifier">Expr</span> + <span class="special">,</span> <span class="identifier">default_context</span> <span class="keyword">const</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">tag_of</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span> + <span class="special">></span> + <span class="special">{};</span> +<span class="special">};</span> +</pre> +<p> + There are a bunch of <code class="computeroutput"><span class="identifier">default_eval</span><span class="special"><></span></code> specializations, each of which + handles a different C++ operator. Here, for instance, is the specialization + for binary addition: + </p> +<pre class="programlisting"><span class="comment">// A default expression evaluator for binary addition</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">default_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span><span class="special">></span> +<span class="special">{</span> +<span class="keyword">private</span><span class="special">:</span> + <span class="keyword">static</span> <span class="identifier">Expr</span> <span class="special">&</span> <span class="identifier">s_expr</span><span class="special">;</span> + <span class="keyword">static</span> <span class="identifier">Context</span> <span class="special">&</span> <span class="identifier">s_ctx</span><span class="special">;</span> + +<span class="keyword">public</span><span class="special">:</span> + <span class="keyword">typedef</span> + <span class="identifier">decltype</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">s_expr</span><span class="special">),</span> <span class="identifier">s_ctx</span><span class="special">)</span> + <span class="special">+</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">s_expr</span><span class="special">),</span> <span class="identifier">s_ctx</span><span class="special">)</span> + <span class="special">)</span> + <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">ctx</span><span class="special">)</span> + <span class="special">+</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + The above code uses <code class="computeroutput"><span class="identifier">decltype</span></code> + to calculate the return type of the function call operator. <code class="computeroutput"><span class="identifier">decltype</span></code> is a new keyword in the + next version of C++ that gets the type of any expression. Most compilers + do not yet support <code class="computeroutput"><span class="identifier">decltype</span></code> + directly, so <code class="computeroutput"><span class="identifier">default_eval</span><span class="special"><></span></code> uses the Boost.Typeof library + to emulate it. On some compilers, that may mean that <code class="computeroutput"><span class="identifier">default_context</span></code> either doesn't work + or that it requires you to register your types with the Boost.Typeof + library. Check the documentation for Boost.Typeof to see. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.null_context"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.null_context" title="null_context"><code class="literal">null_context</code></a> +</h6></div></div></div> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/context/null_context.html" title="Struct null_context">proto::null_context<></a></code> + is a simple context that recursively evaluates children but does not + combine the results in any way and returns void. It is useful in conjunction + with <code class="computeroutput"><span class="identifier">callable_context</span><span class="special"><></span></code>, or when defining your own + contexts which mutate an expression tree in-place rather than accumulate + a result, as we'll see below. + </p> +<p> + <code class="computeroutput"><a class="link" href="../boost/proto/context/null_context.html" title="Struct null_context">proto::null_context<></a></code> + is trivially implemented in terms of <code class="computeroutput"><span class="identifier">null_eval</span><span class="special"><></span></code> as follows: + </p> +<pre class="programlisting"><span class="comment">// Definition of null_context</span> +<span class="keyword">struct</span> <span class="identifier">null_context</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">null_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">null_context</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">Expr</span><span class="special">::</span><span class="identifier">proto_arity</span><span class="special">::</span><span class="identifier">value</span><span class="special">></span> + <span class="special">{};</span> +<span class="special">};</span> +</pre> +<p> + And <code class="computeroutput"><span class="identifier">null_eval</span><span class="special"><></span></code> + is also trivially implemented. Here, for instance is a binary <code class="computeroutput"><span class="identifier">null_eval</span><span class="special"><></span></code>: + </p> +<pre class="programlisting"><span class="comment">// Binary null_eval<></span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Context</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">null_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">Context</span><span class="special">,</span> <span class="number">2</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Context</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + When would such classes be useful? Imagine you have an expression tree + with integer terminals, and you would like to increment each integer + in-place. You might define an evaluation context as follows: + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">increment_ints</span> +<span class="special">{</span> + <span class="comment">// By default, just evaluate all children by delegating</span> + <span class="comment">// to the null_eval<></span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">child</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">null_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">increment_ints</span> <span class="keyword">const</span><span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// Increment integer terminals</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">increment_ints</span> <span class="keyword">const</span> <span class="special">&)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="special">++</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">child</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span> + <span class="special">}</span> + <span class="special">};</span> +<span class="special">};</span> +</pre> +<p> + In the next section on <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code>, + we'll see an even simpler way to achieve the same thing. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.callable_context"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.callable_context" title="callable_context<>"><code class="literal">callable_context<></code></a> +</h6></div></div></div> +<p> + The <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + is a helper that simplifies the job of writing context classes. Rather + than writing template specializations, with <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + you write a function object with an overloaded function call operator. + Any expressions not handled by an overload are automatically dispatched + to a default evaluation context that you can specify. + </p> +<p> + Rather than an evaluation context in its own right, <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + is more properly thought of as a context adaptor. To use it, you must + define your own context that inherits from <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code>. + </p> +<p> + In the <a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_evaluation.canned_contexts.null_context" title="null_context"><code class="literal">null_context</code></a> + section, we saw how to implement an evaluation context that increments + all the integers within an expression tree. Here is how to do the same + thing with the <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code>: + </p> +<pre class="programlisting"><span class="comment">// An evaluation context that increments all</span> +<span class="comment">// integer terminals in-place.</span> +<span class="keyword">struct</span> <span class="identifier">increment_ints</span> + <span class="special">:</span> <span class="identifier">callable_context</span><span class="special"><</span> + <span class="identifier">increment_ints</span> <span class="keyword">const</span> <span class="comment">// derived context</span> + <span class="special">,</span> <span class="identifier">null_context</span> <span class="keyword">const</span> <span class="comment">// fall-back context</span> + <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Handle int terminals here:</span> + <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">&</span><span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="special">++</span><span class="identifier">i</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + With such a context, we can do the following: + </p> +<pre class="programlisting"><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">j</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span> <span class="identifier">i</span> <span class="special">-</span> <span class="identifier">j</span> <span class="special">*</span> <span class="number">3.14</span><span class="special">,</span> <span class="identifier">increment_ints</span><span class="special">()</span> <span class="special">);</span> + +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"i = "</span> <span class="special"><<</span> <span class="identifier">i</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"j = "</span> <span class="special"><<</span> <span class="identifier">j</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + This program outputs the following, which shows that the integers + <code class="computeroutput"><span class="identifier">i</span></code> and <code class="computeroutput"><span class="identifier">j</span></code> have been incremented by <code class="computeroutput"><span class="number">1</span></code>: + </p> +<pre class="programlisting">i = 1 +j = 11 +</pre> +<p> + In the <code class="computeroutput"><span class="identifier">increment_ints</span></code> + context, we didn't have to define any nested <code class="computeroutput"><span class="identifier">eval</span><span class="special"><></span></code> templates. That's because + <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + implements them for us. <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + takes two template parameters: the derived context and a fall-back + context. For each node in the expression tree being evaluated, <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> checks to see if + there is an overloaded <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> in the derived context that accepts + it. Given some expression <code class="computeroutput"><span class="identifier">expr</span></code> + of type <code class="computeroutput"><span class="identifier">Expr</span></code>, and a + context <code class="computeroutput"><span class="identifier">ctx</span></code>, it attempts + to call: + </p> +<pre class="programlisting"><span class="identifier">ctx</span><span class="special">(</span> + <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">::</span><span class="identifier">proto_tag</span><span class="special">()</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">0</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="number">1</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">...</span> +<span class="special">);</span> +</pre> +<p> + Using function overloading and metaprogramming tricks, <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + can detect at compile-time whether such a function exists or not. If + so, that function is called. If not, the current expression is passed + to the fall-back evaluation context to be processed. + </p> +<p> + We saw another example of the <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + when we looked at the simple calculator expression evaluator. There, + we wanted to customize the evaluation of placeholder terminals, and + delegate the handling of all other nodes to the <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code>. We did + that as follows: + </p> +<pre class="programlisting"><span class="comment">// An evaluation context for calculator expressions that</span> +<span class="comment">// explicitly handles placeholder terminals, but defers the</span> +<span class="comment">// processing of all other nodes to the default_context.</span> +<span class="keyword">struct</span> <span class="identifier">calculator_context</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">args</span><span class="special">;</span> + + <span class="comment">// Define the result type of the calculator.</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Handle the placeholders:</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">>)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">args</span><span class="special">[</span><span class="identifier">I</span><span class="special">];</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + In this case, we didn't specify a fall-back context. In that case, + <code class="computeroutput"><a class="link" href="../boost/proto/context/callable_context.html" title="Struct template callable_context">proto::callable_context<></a></code> + uses the <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code>. With + the above <code class="computeroutput"><span class="identifier">calculator_context</span></code> + and a couple of appropriately defined placeholder terminals, we can + evaluate calculator expressions, as demonstrated below: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">placeholder</span> +<span class="special">{};</span> + +<span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> +<span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_2</span> <span class="special">=</span> <span class="special">{{}};</span> +<span class="comment">// ...</span> + +<span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">4</span><span class="special">);</span> +<span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">5</span><span class="special">);</span> + +<span class="keyword">double</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span> <span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">,</span> <span class="identifier">ctx</span> <span class="special">);</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"j = "</span> <span class="special"><<</span> <span class="identifier">j</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +</pre> +<p> + The above code displays the following: + </p> +<pre class="programlisting">j = 20 +</pre> +</div> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation" title="Expression Transformation: Semantic Actions">Expression + Transformation: Semantic Actions</a> +</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.__activating__your_grammars"><span class="quote">“<span class="quote">Activating</span>”</span> + Your Grammars</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.handling_alternation_and_recursion">Handling + Alternation and Recursion</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.callable_transforms">Callable + Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.object_transforms">Object + Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity">Example: + Calculator Arity</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.state">Transforms + With State Accumulation</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.data">Passing + Auxiliary Data to Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.external_transforms">Separating + Grammars And Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.canned_transforms">Proto's + Built-In Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.primitives">Building + Custom Primitive Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.is_callable">Making + Your Transform Callable</a></span></dt> +</dl></div> +<p> + If you have ever built a parser with the help of a tool like Antlr, yacc + or Boost.Spirit, you might be familiar with <span class="emphasis"><em>semantic actions</em></span>. + In addition to allowing you to define the grammar of the language recognized + by the parser, these tools let you embed code within your grammar that + executes when parts of the grammar participate in a parse. Proto has the + equivalent of semantic actions. They are called <span class="emphasis"><em>transforms</em></span>. + This section describes how to embed transforms within your Proto grammars, + turning your grammars into function objects that can manipulate or evaluate + expressions in powerful ways. + </p> +<p> + Proto transforms are an advanced topic. We'll take it slow, using examples + to illustrate the key concepts, starting simple. + </p> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.__activating__your_grammars"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.__activating__your_grammars" title="“Activating” Your Grammars"><span class="quote">“<span class="quote">Activating</span>”</span> + Your Grammars</a> +</h5></div></div></div> +<p> + The Proto grammars we've seen so far are static. You can check at compile-time + to see if an expression type matches a grammar, but that's it. Things + get more interesting when you give them runtime behaviors. A grammar + with embedded transforms is more than just a static grammar. It is a + function object that accepts expressions that match the grammar and does + <span class="emphasis"><em>something</em></span> with them. + </p> +<p> + Below is a very simple grammar. It matches terminal expressions. + </p> +<pre class="programlisting"><span class="comment">// A simple Proto grammar that matches all terminals</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">_</span> <span class="special">></span> +</pre> +<p> + Here is the same grammar with a transform that extracts the value from + the terminal: + </p> +<pre class="programlisting"><span class="comment">// A simple Proto grammar that matches all terminals</span> +<span class="comment">// *and* a function object that extracts the value from</span> +<span class="comment">// the terminal</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> <span class="comment">// <-- Look, a transform!</span> +<span class="special">></span> +</pre> +<p> + You can read this as follows: when you match a terminal expression, extract + the value. The type <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code> + is a so-called transform. Later we'll see what makes it a transform, + but for now just think of it as a kind of function object. Note the use + of <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a></code>: the first template + parameter is the grammar to match and the second is the transform to + execute. The result is both a grammar that matches terminal expressions + and a function object that accepts terminal expressions and extracts + their values. + </p> +<p> + As with ordinary grammars, we can define an empty struct that inherits + from a grammar+transform to give us an easy way to refer back to the + thing we're defining, as follows: + </p> +<pre class="programlisting"><span class="comment">// A grammar and a function object, as before</span> +<span class="keyword">struct</span> <span class="identifier">Value</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// "Value" is a grammar that matches terminal expressions</span> +<span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">Value</span> <span class="special">></span> <span class="special">));</span> + +<span class="comment">// "Value" also defines a function object that accepts terminals</span> +<span class="comment">// and extracts their value.</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">answer</span> <span class="special">=</span> <span class="special">{</span><span class="number">42</span><span class="special">};</span> +<span class="identifier">Value</span> <span class="identifier">get_value</span><span class="special">;</span> +<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">get_value</span><span class="special">(</span> <span class="identifier">answer</span> <span class="special">);</span> +</pre> +<p> + As already mentioned, <code class="computeroutput"><span class="identifier">Value</span></code> + is a grammar that matches terminal expressions and a function object + that operates on terminal expressions. It would be an error to pass a + non-terminal expression to the <code class="computeroutput"><span class="identifier">Value</span></code> + function object. This is a general property of grammars with transforms; + when using them as function objects, expressions passed to them must + match the grammar. + </p> +<p> + Proto grammars are valid TR1-style function objects. That means you can + use <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><></span></code> + to ask a grammar what its return type will be, given a particular expression + type. For instance, we can access the <code class="computeroutput"><span class="identifier">Value</span></code> + grammar's return type as follows: + </p> +<pre class="programlisting"><span class="comment">// We can use boost::result_of<> to get the return type</span> +<span class="comment">// of a Proto grammar.</span> +<span class="keyword">typedef</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">Value</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span><span class="special">)>::</span><span class="identifier">type</span> +<span class="identifier">result_type</span><span class="special">;</span> + +<span class="comment">// Check that we got the type we expected</span> +<span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">result_type</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="special">));</span> +</pre> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + A grammar with embedded transforms is both a grammar and a function + object. Calling these things "grammars with transforms" would + get tedious. We could call them something like "active grammars", + but as we'll see <span class="emphasis"><em>every</em></span> grammar that you can define + with Proto is "active"; that is, every grammar has some behavior + when used as a function object. So we'll continue calling these things + plain "grammars". The term "transform" is reserved + for the thing that is used as the second parameter to the <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a></code> template. + </p></td></tr> +</table></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.handling_alternation_and_recursion"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.handling_alternation_and_recursion" title="Handling Alternation and Recursion">Handling + Alternation and Recursion</a> +</h5></div></div></div> +<p> + Most grammars are a little more complicated than the one in the preceding + section. For the sake of illustration, let's define a rather nonsensical + grammar that matches any expression and recurses to the leftmost terminal + and returns its value. It will demonstrate how two key concepts of Proto + grammars -- alternation and recursion -- interact with transforms. The + grammar is described below. + </p> +<pre class="programlisting"><span class="comment">// A grammar that matches any expression, and a function object</span> +<span class="comment">// that returns the value of the leftmost terminal.</span> +<span class="keyword">struct</span> <span class="identifier">LeftmostLeaf</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="comment">// If the expression is a terminal, return its value</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> + <span class="special">></span> + <span class="comment">// Otherwise, it is a non-terminal. Return the result</span> + <span class="comment">// of invoking LeftmostLeaf on the 0th (leftmost) child.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">_</span> + <span class="special">,</span> <span class="identifier">LeftmostLeaf</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span> <span class="special">)</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// A Proto terminal wrapping std::cout</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">};</span> + +<span class="comment">// Create an expression and use LeftmostLeaf to extract the</span> +<span class="comment">// value of the leftmost terminal, which will be std::cout.</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="identifier">sout</span> <span class="special">=</span> <span class="identifier">LeftmostLeaf</span><span class="special">()(</span> <span class="identifier">cout_</span> <span class="special"><<</span> <span class="string">"the answer: "</span> <span class="special"><<</span> <span class="number">42</span> <span class="special"><<</span> <span class="char">'\n'</span> <span class="special">);</span> +</pre> +<p> + We've seen <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><></span></code> + before. Here it is serving two roles. First, it is a grammar that matches + any of its alternate sub-grammars; in this case, either a terminal or + a non-terminal. Second, it is also a function object that accepts an + expression, finds the alternate sub-grammar that matches the expression, + and applies its transform. And since <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code> + inherits from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><></span></code>, + <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code> is also + both a grammar and a function object. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + The second alternate uses <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> + as its grammar. Recall that <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> + is the wildcard grammar that matches any expression. Since alternates + in <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><></span></code> + are tried in order, and since the first alternate handles all terminals, + the second alternate handles all (and only) non-terminals. Often enough, + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">_</span><span class="special">,</span> + <em class="replaceable"><code>some-transform</code></em> <span class="special">></span></code> + is the last alternate in a grammar, so for improved readability, you + could use the equivalent <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">otherwise</span><span class="special"><</span> <em class="replaceable"><code>some-transform</code></em> + <span class="special">></span></code>. + </p></td></tr> +</table></div> +<p> + The next section describes this grammar further. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.callable_transforms"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.callable_transforms" title="Callable Transforms">Callable + Transforms</a> +</h5></div></div></div> +<p> + In the grammar defined in the preceding section, the transform associated + with non-terminals is a little strange-looking: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">_</span> + <span class="special">,</span> <span class="bold"><strong>LeftmostLeaf( proto::_child0 )</strong></span> <span class="comment">// <-- a "callable" transform</span> +<span class="special">></span> +</pre> +<p> + It has the effect of accepting non-terminal expressions, taking the 0th + (leftmost) child and recursively invoking the <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code> + function on it. But <code class="computeroutput"><span class="identifier">LeftmostLeaf</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span> + <span class="special">)</span></code> is actually a <span class="emphasis"><em>function + type</em></span>. Literally, it is the type of a function that accepts + an object of type <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span></code> + and returns an object of type <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code>. + So how do we make sense of this transform? Clearly, there is no function + that actually has this signature, nor would such a function be useful. + The key is in understanding how <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><></span></code> <span class="emphasis"><em>interprets</em></span> + its second template parameter. + </p> +<p> + When the second template parameter to <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a></code> + is a function type, <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a></code> + interprets the function type as a transform. In this case, <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code> is treated as the type + of a function object to invoke, and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span></code> + is treated as a transform. First, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span></code> + is applied to the current expression (the non-terminal that matched this + alternate sub-grammar), and the result (the 0th child) is passed as an + argument to <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code>. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>Transforms are a Domain-Specific Language</strong></span> + </p> +<p> + <code class="computeroutput"><span class="identifier">LeftmostLeaf</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span> <span class="special">)</span></code> + <span class="emphasis"><em>looks</em></span> like an invocation of the <code class="computeroutput"><span class="identifier">LeftmostLeaf</span></code> function object, but + it's not, but then it actually is! Why this confusing subterfuge? Function + types give us a natural and concise syntax for composing more complicated + transforms from simpler ones. The fact that the syntax is suggestive + of a function invocation is on purpose. It is a embedded domain-specific + language for defining expression transformations. If the subterfuge + worked, it may have fooled you into thinking the transform is doing + exactly what it actually does! And that's the point. + </p> +</td></tr> +</table></div> +<p> + The type <code class="computeroutput"><span class="identifier">LeftmostLeaf</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span> + <span class="special">)</span></code> is an example of a <span class="emphasis"><em>callable + transform</em></span>. It is a function type that represents a function + object to call and its arguments. The types <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span></code> + and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code> are <span class="emphasis"><em>primitive transforms</em></span>. + They are plain structs, not unlike function objects, from which callable + transforms can be composed. There is one other type of transform, <span class="emphasis"><em>object + transforms</em></span>, that we'll encounter next. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.object_transforms"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.object_transforms" title="Object Transforms">Object + Transforms</a> +</h5></div></div></div> +<p> + The very first transform we looked at simply extracted the value of terminals. + Let's do the same thing, but this time we'll promote all ints to longs + first. (Please forgive the contrived-ness of the examples so far; they + get more interesting later.) Here's the grammar: + </p> +<pre class="programlisting"><span class="comment">// A simple Proto grammar that matches all terminals,</span> +<span class="comment">// and a function object that extracts the value from</span> +<span class="comment">// the terminal, promoting ints to longs:</span> +<span class="keyword">struct</span> <span class="identifier">ValueWithPomote</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">></span> + <span class="special">,</span> <span class="keyword">long</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> <span class="comment">// <-- an "object" transform</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">_</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + You can read the above grammar as follows: when you match an int terminal, + extract the value from the terminal and use it to initialize a long; + otherwise, when you match another kind of terminal, just extract the + value. The type <code class="computeroutput"><span class="keyword">long</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span></code> + is a so-called <span class="emphasis"><em>object</em></span> transform. It looks like the + creation of a temporary long, but it's really a function type. Just as + a callable transform is a function type that represents a function to + call and its arguments, an object transforms is a function type that + represents an object to construct and the arguments to its constructor. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>Object Transforms vs. Callable Transforms</strong></span> + </p> +<p> + When using function types as Proto transforms, they can either represent + an object to construct or a function to call. It is similar to "normal" + C++ where the syntax <code class="computeroutput"><span class="identifier">foo</span><span class="special">(</span><span class="string">"arg"</span><span class="special">)</span></code> can either be interpreted as an object + to construct or a function to call, depending on whether <code class="computeroutput"><span class="identifier">foo</span></code> is a type or a function. But + consider two of the transforms we've seen so far: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">LeftmostLeaf</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span><span class="special">)</span> <span class="comment">// <-- a callable transform</span> +<span class="keyword">long</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> <span class="comment">// <-- an object transform</span> +</pre> +<p> + </p> +<p> + Proto can't know in general which is which, so it uses a trait, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_callable</span><span class="special"><></span></code>, + to differentiate. <code class="computeroutput"><span class="identifier">is_callable</span><span class="special"><</span> <span class="keyword">long</span> + <span class="special">>::</span><span class="identifier">value</span></code> + is false so <code class="computeroutput"><span class="keyword">long</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span></code> + is an object to construct, but <code class="computeroutput"><span class="identifier">is_callable</span><span class="special"><</span> <span class="identifier">LeftmostLeaf</span> + <span class="special">>::</span><span class="identifier">value</span></code> + is true so <code class="computeroutput"><span class="identifier">LeftmostLeaf</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span><span class="special">)</span></code> is a function to call. Later on, we'll + see how Proto recognizes a type as "callable". + </p> +</td></tr> +</table></div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity" title="Example: Calculator Arity">Example: + Calculator Arity</a> +</h5></div></div></div> +<p> + Now that we have the basics of Proto transforms down, let's consider + a slightly more realistic example. We can use transforms to improve the + type-safety of the <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">calculator + EDSL</a>. If you recall, it lets you write infix arithmetic expressions + involving argument placeholders like <code class="computeroutput"><span class="identifier">_1</span></code> + and <code class="computeroutput"><span class="identifier">_2</span></code> and pass them + to STL algorithms as function objects, as follows: + </p> +<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">a1</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">56</span><span class="special">,</span> <span class="number">84</span><span class="special">,</span> <span class="number">37</span><span class="special">,</span> <span class="number">69</span> <span class="special">};</span> +<span class="keyword">double</span> <span class="identifier">a2</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">65</span><span class="special">,</span> <span class="number">120</span><span class="special">,</span> <span class="number">60</span><span class="special">,</span> <span class="number">70</span> <span class="special">};</span> +<span class="keyword">double</span> <span class="identifier">a3</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">0</span> <span class="special">};</span> + +<span class="comment">// Use std::transform() and a calculator expression</span> +<span class="comment">// to calculate percentages given two input sequences:</span> +<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">a1</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">+</span><span class="number">4</span><span class="special">,</span> <span class="identifier">a2</span><span class="special">,</span> <span class="identifier">a3</span><span class="special">,</span> <span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">);</span> +</pre> +<p> + This works because we gave calculator expressions an <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> that evaluates the expression, replacing + the placeholders with the arguments to <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>. The overloaded <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><>::</span><span class="keyword">operator</span><span class="special">()</span></code> looked like this: + </p> +<pre class="programlisting"><span class="comment">// Overload operator() to invoke proto::eval() with</span> +<span class="comment">// our calculator_context.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">double</span> +<span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">a1</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">a2</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">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a1</span><span class="special">);</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a2</span><span class="special">);</span> + + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + Although this works, it's not ideal because it doesn't warn users if + they supply too many or too few arguments to a calculator expression. + Consider the following mistakes: + </p> +<pre class="programlisting"><span class="special">(</span><span class="identifier">_1</span> <span class="special">*</span> <span class="identifier">_1</span><span class="special">)(</span><span class="number">4</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// Oops, too many arguments!</span> +<span class="special">(</span><span class="identifier">_2</span> <span class="special">*</span> <span class="identifier">_2</span><span class="special">)(</span><span class="number">42</span><span class="special">);</span> <span class="comment">// Oops, too few arguments!</span> +</pre> +<p> + The expression <code class="computeroutput"><span class="identifier">_1</span> <span class="special">*</span> + <span class="identifier">_1</span></code> defines a unary calculator + expression; it takes one argument and squares it. If we pass more than + one argument, the extra arguments will be silently ignored, which might + be surprising to users. The next expression, <code class="computeroutput"><span class="identifier">_2</span> + <span class="special">*</span> <span class="identifier">_2</span></code> + defines a binary calculator expression; it takes two arguments, ignores + the first and squares the second. If we only pass one argument, the code + silently fills in <code class="computeroutput"><span class="number">0.0</span></code> for + the second argument, which is also probably not what users expect. What + can be done? + </p> +<p> + We can say that the <span class="emphasis"><em>arity</em></span> of a calculator expression + is the number of arguments it expects, and it is equal to the largest + placeholder in the expression. So, the arity of <code class="computeroutput"><span class="identifier">_1</span> + <span class="special">*</span> <span class="identifier">_1</span></code> + is one, and the arity of <code class="computeroutput"><span class="identifier">_2</span> + <span class="special">*</span> <span class="identifier">_2</span></code> + is two. We can increase the type-safety of our calculator EDSL by making + sure the arity of an expression equals the actual number of arguments + supplied. Computing the arity of an expression is simple with the help + of Proto transforms. + </p> +<p> + It's straightforward to describe in words how the arity of an expression + should be calculated. Consider that calculator expressions can be made + of <code class="computeroutput"><span class="identifier">_1</span></code>, <code class="computeroutput"><span class="identifier">_2</span></code>, literals, unary expressions and + binary expressions. The following table shows the arities for each of + these 5 constituents. + </p> +<div class="table"> +<a name="boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity.t0"></a><p class="title"><b>Table 20.8. Calculator Sub-Expression Arities</b></p> +<div class="table-contents"><table class="table" summary="Calculator Sub-Expression Arities"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Sub-Expression + </p> + </th> +<th> + <p> + Arity + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + Placeholder 1 + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="number">1</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + Placeholder 2 + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="number">2</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + Literal + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="number">0</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + Unary Expression + </p> + </td> +<td> + <p> + <span class="emphasis"><em>arity of the operand</em></span> + </p> + </td> +</tr> +<tr> +<td> + <p> + Binary Expression + </p> + </td> +<td> + <p> + <span class="emphasis"><em>max arity of the two operands</em></span> + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><p> + Using this information, we can write the grammar for calculator expressions + and attach transforms for computing the arity of each constituent. The + code below computes the expression arity as a compile-time integer, using + integral wrappers and metafunctions from the Boost MPL Library. The grammar + is described below. + </p> +<p> +</p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">CalcArity</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">></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="number">1</span><span class="special">>()</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">></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="number">2</span><span class="special">>()</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</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="number">0</span><span class="special">>()</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">CalcArity</span><span class="special">>,</span> + <span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child</span><span class="special">)</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">binary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">CalcArity</span><span class="special">,</span> <span class="identifier">CalcArity</span><span class="special">>,</span> + <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><</span><span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">),</span> + <span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">)>()</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + </p> +<p> + When we find a placeholder terminal or a literal, we use an <span class="emphasis"><em>object + transform</em></span> such as <code class="computeroutput"><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">int_</span><span class="special"><</span><span class="number">1</span><span class="special">>()</span></code> + to create a (default-constructed) compile-time integer representing the + arity of that terminal. + </p> +<p> + For unary expressions, we use <code class="computeroutput"><span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child</span><span class="special">)</span></code> which is a <span class="emphasis"><em>callable transform</em></span> + that computes the arity of the expression's child. + </p> +<p> + The transform for binary expressions has a few new tricks. Let's look + more closely: + </p> +<pre class="programlisting"><span class="comment">// Compute the left and right arities and</span> +<span class="comment">// take the larger of the two.</span> +<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><</span><span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">),</span> + <span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">)>()</span> +</pre> +<p> + This is an object transform; it default-constructs ... what exactly? + The <code class="computeroutput"><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><></span></code> + template is an MPL metafunction that accepts two compile-time integers. + It has a nested <code class="computeroutput"><span class="special">::</span><span class="identifier">type</span></code> + typedef (not shown) that is the maximum of the two. But here, we appear + to be passing it two things that are <span class="emphasis"><em>not</em></span> compile-time + integers; they're Proto callable transforms. Proto is smart enough to + recognize that fact. It first evaluates the two nested callable transforms, + computing the arities of the left and right child expressions. Then it + puts the resulting integers into <code class="computeroutput"><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><></span></code> and evaluates the metafunction + by asking for the nested <code class="computeroutput"><span class="special">::</span><span class="identifier">type</span></code>. That is the type of the object + that gets default-constructed and returned. + </p> +<p> + More generally, when evaluating object transforms, Proto looks at the + object type and checks whether it is a template specialization, like + <code class="computeroutput"><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><></span></code>. + If it is, Proto looks for nested transforms that it can evaluate. After + any nested transforms have been evaluated and substituted back into the + template, the new template specialization is the result type, unless + that type has a nested <code class="computeroutput"><span class="special">::</span><span class="identifier">type</span></code>, in which case that becomes the + result. + </p> +<p> + Now that we can calculate the arity of a calculator expression, let's + redefine the <code class="computeroutput"><span class="identifier">calculator</span><span class="special"><></span></code> expression wrapper we wrote in + the Getting Started guide to use the <code class="computeroutput"><span class="identifier">CalcArity</span></code> + grammar and some macros from Boost.MPL to issue compile-time errors when + users specify too many or too few arguments. + </p> +<pre class="programlisting"><span class="comment">// The calculator expression wrapper, as defined in the Hello</span> +<span class="comment">// Calculator example in the Getting Started guide. It behaves</span> +<span class="comment">// just like the expression it wraps, but with extra operator()</span> +<span class="comment">// member functions that evaluate the expression.</span> +<span class="comment">// NEW: Use the CalcArity grammar to ensure that the correct</span> +<span class="comment">// number of arguments are supplied.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> + <span class="identifier">base_type</span><span class="special">;</span> + + <span class="identifier">calculator</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="comment">// Use CalcArity to compute the arity of Expr: </span> + <span class="keyword">static</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">arity</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">CalcArity</span><span class="special">(</span><span class="identifier">Expr</span><span class="special">)>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value</span><span class="special">;</span> + + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">BOOST_MPL_ASSERT_RELATION</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">==,</span> <span class="identifier">arity</span><span class="special">);</span> + <span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">a1</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">BOOST_MPL_ASSERT_RELATION</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="special">==,</span> <span class="identifier">arity</span><span class="special">);</span> + <span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a1</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">a1</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">a2</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">BOOST_MPL_ASSERT_RELATION</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="special">==,</span> <span class="identifier">arity</span><span class="special">);</span> + <span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a1</span><span class="special">);</span> + <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a2</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + Note the use of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><></span></code> to access the return type of + the <code class="computeroutput"><span class="identifier">CalcArity</span></code> function + object. Since we used compile-time integers in our transforms, the arity + of the expression is encoded in the return type of the <code class="computeroutput"><span class="identifier">CalcArity</span></code> function object. Proto grammars + are valid TR1-style function objects, so you can use <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><></span></code> to figure out their return types. + </p> +<p> + With our compile-time assertions in place, when users provide too many + or too few arguments to a calculator expression, as in: + </p> +<pre class="programlisting"><span class="special">(</span><span class="identifier">_2</span> <span class="special">*</span> <span class="identifier">_2</span><span class="special">)(</span><span class="number">42</span><span class="special">);</span> <span class="comment">// Oops, too few arguments!</span> +</pre> +<p> + ... they will get a compile-time error message on the line with the assertion + that reads something like this<sup>[<a name="boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity.f0" href="#ftn.boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity.f0" class="footnote">5</a>]</sup>: + </p> +<pre class="programlisting">c:\boost\org\trunk\libs\proto\scratch\main.cpp(97) : error C2664: 'boost::mpl::asse +rtion_failed' : cannot convert parameter 1 from 'boost::mpl::failed ************boo +st::mpl::assert_relation<x,y,__formal>::************' to 'boost::mpl::assert<false> +::type' + with + [ + x=1, + y=2, + __formal=bool boost::mpl::operator==(boost::mpl::failed,boost::mpl::failed) + ] +</pre> +<p> + The point of this exercise was to show that we can write a fairly simple + Proto grammar with embedded transforms that is declarative and readable + and can compute interesting properties of arbitrarily complicated expressions. + But transforms can do more than that. Boost.Xpressive uses transforms + to turn expressions into finite state automata for matching regular expressions, + and Boost.Spirit uses transforms to build recursive descent parser generators. + Proto comes with a collection of built-in transforms that you can use + to perform very sophisticated expression manipulations like these. In + the next few sections we'll see some of them in action. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.state"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.state" title="Transforms With State Accumulation">Transforms + With State Accumulation</a> +</h5></div></div></div> +<p> + So far, we've only seen examples of grammars with transforms that accept + one argument: the expression to transform. But consider for a moment + how, in ordinary procedural code, you would turn a binary tree into a + linked list. You would start with an empty list. Then, you would recursively + convert the right branch to a list, and use the result as the initial + state while converting the left branch to a list. That is, you would + need a function that takes two parameters: the current node and the list + so far. These sorts of <span class="emphasis"><em>accumulation</em></span> problems are + quite common when processing trees. The linked list is an example of + an accumulation variable or <span class="emphasis"><em>state</em></span>. Each iteration + of the algorithm takes the current element and state, applies some binary + function to the two and creates a new state. In the STL, this algorithm + is called <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">accumulate</span><span class="special">()</span></code>. + In many other languages, it is called <span class="emphasis"><em>fold</em></span>. Let's + see how to implement a fold algorithm with Proto transforms. + </p> +<p> + All Proto grammars can optionally accept a state parameter in addition + to the expression to transform. If you want to fold a tree to a list, + you'll need to make use of the state parameter to pass around the list + you've built so far. As for the list, the Boost.Fusion library provides + a <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">cons</span><span class="special"><></span></code> + type from which you can build heterogeneous lists. The type <code class="computeroutput"><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">nil</span></code> represents an empty list. + </p> +<p> + Below is a grammar that recognizes output expressions like <code class="computeroutput"><span class="identifier">cout_</span> <span class="special"><<</span> + <span class="number">42</span> <span class="special"><<</span> + <span class="char">'\n'</span></code> and puts the arguments into + a Fusion list. It is explained below. + </p> +<pre class="programlisting"><span class="comment">// Fold the terminals in output statements like</span> +<span class="comment">// "cout_ << 42 << '\n'" into a Fusion cons-list.</span> +<span class="keyword">struct</span> <span class="identifier">FoldToList</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="comment">// Don't add the ostream terminal to the list</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span> + <span class="special">></span> + <span class="comment">// Put all other terminals at the head of the</span> + <span class="comment">// list that we're building in the "state" parameter</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">cons</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">>(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span> + <span class="special">)</span> + <span class="special">></span> + <span class="comment">// For left-shift operations, first fold the right</span> + <span class="comment">// child to a list using the current state. Use</span> + <span class="comment">// the result as the state parameter when folding</span> + <span class="comment">// the left child to a list.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><</span><span class="identifier">FoldToList</span><span class="special">,</span> <span class="identifier">FoldToList</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">FoldToList</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span> + <span class="special">,</span> <span class="identifier">FoldToList</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">)</span> + <span class="special">)</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Before reading on, see if you can apply what you know already about object, + callable and primitive transforms to figure out how this grammar works. + </p> +<p> + When you use the <code class="computeroutput"><span class="identifier">FoldToList</span></code> + function, you'll need to pass two arguments: the expression to fold, + and the initial state: an empty list. Those two arguments get passed + around to each transform. We learned previously that <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code> + is a primitive transform that accepts a terminal expression and extracts + its value. What we didn't know until now was that it also accepts the + current state <span class="emphasis"><em>and ignores it</em></span>. <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span></code> + is also a primitive transform. It accepts the current expression, which + it ignores, and the current state, which it returns. + </p> +<p> + When we find a terminal, we stick it at the head of the cons list, using + the current state as the tail of the list. (The first alternate causes + the <code class="computeroutput"><span class="identifier">ostream</span></code> to be skipped. + We don't want <code class="computeroutput"><span class="identifier">cout</span></code> in + the list.) When we find a shift-left node, we apply the following transform: + </p> +<pre class="programlisting"><span class="comment">// Fold the right child and use the result as</span> +<span class="comment">// state while folding the right.</span> +<span class="identifier">FoldToList</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span> + <span class="special">,</span> <span class="identifier">FoldToList</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">)</span> +<span class="special">)</span> +</pre> +<p> + You can read this transform as follows: using the current state, fold + the right child to a list. Use the new list as the state while folding + the left child to a list. + </p> +<div class="tip"><table border="0" summary="Tip"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td> +<th align="left">Tip</th> +</tr> +<tr><td align="left" valign="top"> +<p> + If your compiler is Microsoft Visual C++, you'll find that the above + transform does not compile. The compiler has bugs with its handling + of nested function types. You can work around the bug by wrapping the + inner transform in <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><></span></code> as follows: + </p> +<p> +</p> +<pre class="programlisting"><span class="identifier">FoldToList</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><span class="identifier">FoldToList</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">)></span> +<span class="special">)</span> +</pre> +<p> + </p> +<p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><></span></code> + turns a callable transform into a primitive transform, but more on + that later. + </p> +</td></tr> +</table></div> +<p> + Now that we have defined the <code class="computeroutput"><span class="identifier">FoldToList</span></code> + function object, we can use it to turn output expressions into lists + as follows: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">};</span> + +<span class="comment">// This is the type of the list we build below</span> +<span class="keyword">typedef</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">cons</span><span class="special"><</span> + <span class="keyword">int</span> + <span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">cons</span><span class="special"><</span> + <span class="keyword">double</span> + <span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">cons</span><span class="special"><</span> + <span class="keyword">char</span> + <span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">nil</span> + <span class="special">></span> + <span class="special">></span> + <span class="special">></span> +<span class="identifier">result_type</span><span class="special">;</span> + +<span class="comment">// Fold an output expression into a Fusion list, using</span> +<span class="comment">// fusion::nil as the initial state of the transformation.</span> +<span class="identifier">FoldToList</span> <span class="identifier">to_list</span><span class="special">;</span> +<span class="identifier">result_type</span> <span class="identifier">args</span> <span class="special">=</span> <span class="identifier">to_list</span><span class="special">(</span><span class="identifier">cout_</span> <span class="special"><<</span> <span class="number">1</span> <span class="special"><<</span> <span class="number">3.14</span> <span class="special"><<</span> <span class="char">'\n'</span><span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">nil</span><span class="special">());</span> + +<span class="comment">// Now "args" is the list: {1, 3.14, '\n'}</span> +</pre> +<p> + When writing transforms, "fold" is such a basic operation that + Proto provides a number of built-in fold transforms. We'll get to them + later. For now, rest assured that you won't always have to stretch your + brain so far to do such basic things. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.data"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.data" title="Passing Auxiliary Data to Transforms">Passing + Auxiliary Data to Transforms</a> +</h5></div></div></div> +<p> + In the last section, we saw that we can pass a second parameter to grammars + with transforms: an accumulation variable or <span class="emphasis"><em>state</em></span> + that gets updated as your transform executes. There are times when your + transforms will need to access auxiliary data that does <span class="emphasis"><em>not</em></span> + accumulate, so bundling it with the state parameter is impractical. Instead, + you can pass auxiliary data as a third parameter, known as the <span class="emphasis"><em>data</em></span> + parameter. Below we show an example involving string processing where + the data parameter is essential. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + All Proto grammars are function objects that take one, two or three + arguments: the expression, the state, and the data. There are no additional + arguments to know about, we promise. In Haskell, there is set of tree + traversal technologies known collectively as <a class="link" href="users_guide.html#boost_proto.users_guide.resources.SYB"><span class="quote">“<span class="quote">Scrap + Your Boilerplate</span>”</span></a>. In that framework, there are also + three parameters: the term, the accumulator, and the context. These + are Proto's expression, state and data parameters under different names. + </p></td></tr> +</table></div> +<p> + Expression templates are often used as an optimization to eliminate temporary + objects. Consider the problem of string concatenation: a series of concatenations + would result in the needless creation of temporary strings. We can use + Proto to make string concatenation very efficient. To make the problem + more interesting, we can apply a locale-sensitive transformation to each + character during the concatenation. The locale information will be passed + as the data parameter. + </p> +<p> + Consider the following expression template: + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">+</span> <span class="string">" "</span> <span class="special">+</span> <span class="string">"world"</span><span class="special">;</span> +</pre> +<p> + We would like to concatenate this string into a statically allocated + wide character buffer, widening each character in turn using the specified + locale. The first step is to write a grammar that describes this expression, + with transforms that calculate the total string length. Here it is: + </p> +<pre class="programlisting"><span class="comment">// A grammar that matches string concatenation expressions, and</span> +<span class="comment">// a transform that calculates the total string length.</span> +<span class="keyword">struct</span> <span class="identifier">StringLength</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="comment">// When you find a character array ...</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span><span class="special">[</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">N</span><span class="special">]></span> + <span class="comment">// ... the length is the size of the array minus 1.</span> + <span class="special">,</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">prior</span><span class="special"><</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">sizeof_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">></span> <span class="special">>()</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="comment">// The length of a concatenated string is ...</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">StringLength</span><span class="special">,</span> <span class="identifier">StringLength</span><span class="special">></span> + <span class="comment">// ... the sum of the lengths of each sub-string.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span> + <span class="identifier">_</span> + <span class="special">,</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">size_t</span><span class="special"><</span><span class="number">0</span><span class="special">>()</span> + <span class="special">,</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">StringLength</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">>()</span> + <span class="special">></span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Notice the use of <code class="computeroutput"><a class="link" href="../boost/proto/fold.html" title="Struct template fold">proto::fold<></a></code>. It is a primitive + transform that takes a sequence, a state, and function, just like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">accumulate</span><span class="special">()</span></code>. + The three template parameters are transforms. The first yields the sequence + of expressions over which to fold, the second yields the initial state + of the fold, and the third is the function to apply at each iteration. + The use of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> as the first parameter might have + you confused. In addition to being Proto's wildcard, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code> + is also a primitive transform that returns the current expression, which + (if it is a non-terminal) is a sequence of its child expressions. + </p> +<p> + Next, we need a function object that accepts a narrow string, a wide + character buffer, and a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ctype</span><span class="special"><></span></code> facet for doing the locale-specific + stuff. It's fairly straightforward. + </p> +<pre class="programlisting"><span class="comment">// A function object that writes a narrow string</span> +<span class="comment">// into a wide buffer.</span> +<span class="keyword">struct</span> <span class="identifier">WidenCopy</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">wchar_t</span> <span class="special">*</span><span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">wchar_t</span> <span class="special">*</span> + <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">char</span> <span class="keyword">const</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">wchar_t</span> <span class="special">*</span><span class="identifier">buf</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ctype</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">ct</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">for</span><span class="special">(;</span> <span class="special">*</span><span class="identifier">str</span><span class="special">;</span> <span class="special">++</span><span class="identifier">str</span><span class="special">,</span> <span class="special">++</span><span class="identifier">buf</span><span class="special">)</span> + <span class="special">*</span><span class="identifier">buf</span> <span class="special">=</span> <span class="identifier">ct</span><span class="special">.</span><span class="identifier">widen</span><span class="special">(*</span><span class="identifier">str</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">buf</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> +</pre> +<p> + Finally, we need some transforms that actually walk the concatenated + string expression, widens the characters and writes them to a buffer. + We will pass a <code class="computeroutput"><span class="keyword">wchar_t</span><span class="special">*</span></code> + as the state parameter and update it as we go. We'll also pass the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ctype</span><span class="special"><></span></code> + facet as the data parameter. It looks like this: + </p> +<pre class="programlisting"><span class="comment">// Write concatenated strings into a buffer, widening</span> +<span class="comment">// them as we go.</span> +<span class="keyword">struct</span> <span class="identifier">StringCopy</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">char</span><span class="special">[</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">N</span><span class="special">]></span> + <span class="special">,</span> <span class="identifier">WidenCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">StringCopy</span><span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span> + <span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span> + <span class="special">)</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Let's look more closely at the transform associated with non-terminals: + </p> +<pre class="programlisting"><span class="identifier">StringCopy</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span> + <span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span> +<span class="special">)</span> +</pre> +<p> + This bears a resemblance to the transform in the previous section that + folded an expression tree into a list. First we recurse on the left child, + writing its strings into the <code class="computeroutput"><span class="keyword">wchar_t</span><span class="special">*</span></code> passed in as the state parameter. That + returns the new value of the <code class="computeroutput"><span class="keyword">wchar_t</span><span class="special">*</span></code>, which is passed as state while transforming + the right child. Both invocations receive the same <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ctype</span><span class="special"><></span></code>, which is passed in as the data + parameter. + </p> +<p> + With these pieces in our pocket, we can implement our concatenate-and-widen + function as follows: + </p> +<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">void</span> <span class="identifier">widen</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="comment">// Make sure the expression conforms to our grammar</span> + <span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">StringLength</span><span class="special">></span> <span class="special">));</span> + + <span class="comment">// Calculate the length of the string and allocate a buffer statically</span> + <span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="keyword">const</span> <span class="identifier">length</span> <span class="special">=</span> + <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">StringLength</span><span class="special">(</span><span class="identifier">Expr</span><span class="special">)>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value</span><span class="special">;</span> + <span class="keyword">wchar_t</span> <span class="identifier">buffer</span><span class="special">[</span> <span class="identifier">length</span> <span class="special">+</span> <span class="number">1</span> <span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">L</span><span class="char">'\0'</span><span class="special">};</span> + + <span class="comment">// Get the current ctype facet</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">loc</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ctype</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">ct</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">use_facet</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ctype</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="special">>(</span><span class="identifier">loc</span><span class="special">));</span> + + <span class="comment">// Concatenate and widen the string expression</span> + <span class="identifier">StringCopy</span><span class="special">()(</span><span class="identifier">expr</span><span class="special">,</span> <span class="special">&</span><span class="identifier">buffer</span><span class="special">[</span><span class="number">0</span><span class="special">],</span> <span class="identifier">ct</span><span class="special">);</span> + + <span class="comment">// Write out the buffer.</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">wcout</span> <span class="special"><<</span> <span class="identifier">buffer</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">widen</span><span class="special">(</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">lit</span><span class="special">(</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">+</span> <span class="string">" "</span> <span class="special">+</span> <span class="string">"world"</span> <span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + The above code displays: + </p> +<pre class="programlisting">hello world +</pre> +<p> + This is a rather round-about way of demonstrating that you can pass extra + data to a transform as a third parameter. There are no restrictions on + what this parameter can be, and (unlike the state parameter) Proto will + never mess with it. + </p> +<h6> +<a name="boost_proto.users_guide.back_end.expression_transformation.data.h0"></a> + <span><a name="boost_proto.users_guide.back_end.expression_transformation.data.implicit_parameters_to_primitive_transforms"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.data.implicit_parameters_to_primitive_transforms">Implicit + Parameters to Primitive Transforms</a> + </h6> +<p> + Let's use the above example to illustrate some other niceties of Proto + transforms. We've seen that grammars, when used as function objects, + can accept up to 3 parameters, and that when using these grammars in + callable transforms, you can also specify up to 3 parameters. Let's take + another look at the transform associated with non-terminals above: + </p> +<pre class="programlisting"><span class="identifier">StringCopy</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span> + <span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span> +<span class="special">)</span> +</pre> +<p> + Here we specify all three parameters to both invocations of the <code class="computeroutput"><span class="identifier">StringCopy</span></code> grammar. But we don't have + to specify all three. If we don't specify a third parameter, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span></code> is assumed. Likewise for the + second parameter and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span></code>. + So the above transform could have been written more simply as: + </p> +<pre class="programlisting"><span class="identifier">StringCopy</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span> + <span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">)</span> +<span class="special">)</span> +</pre> +<p> + The same is true for any primitive transform. The following are all equivalent: + </p> +<div class="table"> +<a name="boost_proto.users_guide.back_end.expression_transformation.data.t0"></a><p class="title"><b>Table 20.9. Implicit Parameters to Primitive Transforms</b></p> +<div class="table-contents"><table class="table" summary="Implicit Parameters to Primitive Transforms"> +<colgroup><col></colgroup> +<thead><tr><th> + <p> + Equivalent Transforms + </p> + </th></tr></thead> +<tbody> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">StringCopy</span><span class="special">></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">StringCopy</span><span class="special">()></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">_</span><span class="special">)></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">)></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">_</span><span class="special">,</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)></span></code> + </p> + </td></tr> +</tbody> +</table></div> +</div> +<br class="table-break"><div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>Grammars Are Primitive Transforms Are Function + Objects</strong></span> + </p> +<p> + So far, we've said that all Proto grammars are function objects. But + it's more accurate to say that Proto grammars are primitive transforms + -- a special kind of function object that takes between 1 and 3 arguments, + and that Proto knows to treat specially when used in a callable transform, + as in the table above. + </p> +</td></tr> +</table></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"> +<p> + <span class="bold"><strong>Not All Function Objects Are Primitive Transforms</strong></span> + </p> +<p> + You might be tempted now to drop the <code class="computeroutput"><span class="identifier">_state</span></code> + and <code class="computeroutput"><span class="identifier">_data</span></code> parameters + to <code class="computeroutput"><span class="identifier">WidenCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">,</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)</span></code>. + That would be an error. <code class="computeroutput"><span class="identifier">WidenCopy</span></code> + is just a plain function object, not a primitive transform, so you + must specify all its arguments. We'll see later how to write your own + primitive transforms. + </p> +</td></tr> +</table></div> +<p> + Once you know that primitive transforms will always receive all three + parameters -- expression, state, and data -- it makes things possible + that wouldn't be otherwise. For instance, consider that for binary expressions, + these two transforms are equivalent. Can you see why? + </p> +<div class="table"> +<a name="boost_proto.users_guide.back_end.expression_transformation.data.t1"></a><p class="title"><b>Table 20.10. Two Equivalent Transforms</b></p> +<div class="table-contents"><table class="table" summary="Two Equivalent Transforms"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Without <code class="literal">proto::fold<></code> + </p> + </th> +<th> + <p> + With <code class="literal">proto::fold<></code> + </p> + </th> +</tr></thead> +<tbody><tr> +<td> + <p> +</p> +<pre class="programlisting"><span class="identifier">StringCopy</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span> + <span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span> +<span class="special">)</span></pre> +<p> + </p> + </td> +<td> + <p> +</p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">StringCopy</span><span class="special">></span></pre> +<p> + </p> + </td> +</tr></tbody> +</table></div> +</div> +<br class="table-break"> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.external_transforms"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.external_transforms" title="Separating Grammars And Transforms">Separating + Grammars And Transforms</a> +</h5></div></div></div> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + This is an advanced topic that is only necessary for people defining + large EDSLs. Feel free to skip this if you're just getting started + with Proto. + </p></td></tr> +</table></div> +<p> + So far, we've seen examples of grammars with embedded transforms. In + practice, grammars can get pretty large, and you may want to use them + to drive several different computations. For instance, you may have a + grammar for a linear algebra domain, and you may want to use it to compute + the shape of the result (vector or matrix?) and also to compute the result + optimally. You don't want to have to copy and paste the whole shebang + just to tweak one of the embedded transforms. What you want instead is + to define the grammar once, and specify the transforms later when you're + ready to evaluate an expression. For that, you use <span class="emphasis"><em>external + transforms</em></span>. The pattern you'll use is this: replace one or + more of the transforms in your grammar with the special placeholder + <code class="computeroutput"><a class="link" href="../boost/proto/external_transform.html" title="Struct external_transform">proto::external_transform</a></code>. + Then, you'll create a bundle of transforms that you will pass to the + grammar in the data parameter (the 3rd parameter after the expression + and state) when evaluating it. + </p> +<p> + To illustrate external transforms, we'll build a calculator evaluator + that can be configured to throw an exception on division by zero. Here + is a bare-bones front end that defines a domain, a grammar, an expression + wrapper, and some placeholder terminals. + </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">assert</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">mpl</span><span class="special">/</span><span class="keyword">int</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">container</span><span class="special">/</span><span class="identifier">vector</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">container</span><span class="special">/</span><span class="identifier">generation</span><span class="special">/</span><span class="identifier">make_vector</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">proto</span><span class="special">/</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">fusion</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="comment">// The argument placeholder type</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">placeholder</span> <span class="special">:</span> <span class="identifier">I</span> <span class="special">{};</span> + +<span class="comment">// The grammar for valid calculator expressions</span> +<span class="keyword">struct</span> <span class="identifier">calc_grammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</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">E</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">calc_expr</span><span class="special">;</span> +<span class="keyword">struct</span> <span class="identifier">calc_domain</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">calc_expr</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">E</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calc_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">E</span><span class="special">,</span> <span class="identifier">calc_expr</span><span class="special"><</span><span class="identifier">E</span><span class="special">>,</span> <span class="identifier">calc_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">calc_expr</span><span class="special">(</span><span class="identifier">E</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">e</span> <span class="special">=</span> <span class="identifier">E</span><span class="special">())</span> <span class="special">:</span> <span class="identifier">calc_expr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span> <span class="special">{}</span> +<span class="special">};</span> + +<span class="identifier">calc_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</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="number">0</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="identifier">_1</span><span class="special">;</span> +<span class="identifier">calc_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</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="number">1</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="identifier">_2</span><span class="special">;</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Build a calculator expression, and do nothing with it.</span> + <span class="special">(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="identifier">_2</span><span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + Now, let's embed transforms into <code class="computeroutput"><span class="identifier">calc_grammar</span></code> + so that we can use it to evaluate calculator expressions: + </p> +<pre class="programlisting"><span class="comment">// The calculator grammar with embedded transforms for evaluating expression.</span> +<span class="keyword">struct</span> <span class="identifier">calc_grammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">at</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + With this definition of <code class="computeroutput"><span class="identifier">calc_grammar</span></code> + we can evaluate expressions by passing along a Fusion vector containing + the values to use for the <code class="computeroutput"><span class="identifier">_1</span></code> + and <code class="computeroutput"><span class="identifier">_2</span></code> placeholders: + </p> +<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">calc_grammar</span><span class="special">()(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="identifier">_2</span><span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">make_vector</span><span class="special">(</span><span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">));</span> +<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="number">7</span><span class="special">);</span> +</pre> +<p> + We also want an alternative evaluation strategy that checks for division + by zero and throws an exception. Just how ridiculous would it be to copy + the entire <code class="computeroutput"><span class="identifier">calc_grammar</span></code> + just to change the one line that transforms division expressions?! External + transforms are ideally suited to this problem. + </p> +<p> + First, we give the division rule in our grammar a "name"; that + is, we make it a struct. We'll use this unique type later to dispatch + to the right transforms. + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">calc_grammar</span><span class="special">;</span> +<span class="keyword">struct</span> <span class="identifier">divides_rule</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> <span class="special">{};</span> +</pre> +<p> + Next, we change <code class="computeroutput"><span class="identifier">calc_grammar</span></code> + to make the handling of division expressions external. + </p> +<pre class="programlisting"><span class="comment">// The calculator grammar with an external transform for evaluating</span> +<span class="comment">// division expressions.</span> +<span class="keyword">struct</span> <span class="identifier">calc_grammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="comment">/* ... as before ... */</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">divides_rule</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">external_transform</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The use of <code class="computeroutput"><a class="link" href="../boost/proto/external_transform.html" title="Struct external_transform">proto::external_transform</a></code> above + makes the handling of division expressions externally parameterizeable. + </p> +<p> + Next, we use <code class="computeroutput"><a class="link" href="../boost/proto/external_transforms.html" title="Struct template external_transforms">proto::external_transforms<></a></code> + (note the trailing 's') to capture our evaluation strategy in a bundle + that we can pass along to the transform in the data parameter. Read on + for the explanation. + </p> +<pre class="programlisting"><span class="comment">// Evaluate division nodes as before</span> +<span class="keyword">struct</span> <span class="identifier">non_checked_division</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">external_transforms</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">divides_rule</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">/* ... */</span> + +<span class="identifier">non_checked_division</span> <span class="identifier">non_checked</span><span class="special">;</span> +<span class="keyword">int</span> <span class="identifier">result2</span> <span class="special">=</span> <span class="identifier">calc_grammar</span><span class="special">()(</span><span class="identifier">_1</span> <span class="special">/</span> <span class="identifier">_2</span><span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">make_vector</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">2</span><span class="special">),</span> <span class="identifier">non_checked</span><span class="special">);</span> +</pre> +<p> + The struct <code class="computeroutput"><span class="identifier">non_cecked_division</span></code> + associates the transform <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span></code> with the <code class="computeroutput"><span class="identifier">divides_rule</span></code> + grammar rule. An instance of that struct is passed along as the third + parameter when invoking <code class="computeroutput"><span class="identifier">calc_grammar</span></code>. + </p> +<p> + Now, let's implement checked division. The rest should be unsurprising. + </p> +<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">division_by_zero</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span> <span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">do_checked_divide</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">result_type</span><span class="special">;</span> + <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">left</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">right</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">right</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">throw</span> <span class="identifier">division_by_zero</span><span class="special">();</span> + <span class="keyword">return</span> <span class="identifier">left</span> <span class="special">/</span> <span class="identifier">right</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">struct</span> <span class="identifier">checked_division</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">external_transforms</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">divides_rule</span> + <span class="special">,</span> <span class="identifier">do_checked_divide</span><span class="special">(</span><span class="identifier">calc_grammar</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">),</span> <span class="identifier">calc_grammar</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">))</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">/* ... */</span> + +<span class="keyword">try</span> +<span class="special">{</span> + <span class="identifier">checked_division</span> <span class="identifier">checked</span><span class="special">;</span> + <span class="keyword">int</span> <span class="identifier">result3</span> <span class="special">=</span> <span class="identifier">calc_grammar_extern</span><span class="special">()(</span><span class="identifier">_1</span> <span class="special">/</span> <span class="identifier">_2</span><span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">make_vector</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> <span class="identifier">checked</span><span class="special">);</span> +<span class="special">}</span> +<span class="keyword">catch</span><span class="special">(</span><span class="identifier">division_by_zero</span><span class="special">)</span> +<span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"caught division by zero!\n"</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + The above code demonstrates how a single grammar can be used with different + transforms specified externally. This makes it possible to reuse a grammar + to drive several different computations. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.canned_transforms" title="Proto's Built-In Transforms">Proto's + Built-In Transforms</a> +</h5></div></div></div> +<p> + Primitive transforms are the building blocks for more interesting composite + transforms. Proto defines a bunch of generally useful primitive transforms. + They are summarized below. + </p> +<div class="variablelist"> +<p class="title"><b></b></p> +<dl> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_value.html" title="Struct _value">proto::_value</a></code></span></dt> +<dd><p> + Given a terminal expression, return the value of the terminal. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_child_c.html" title="Struct template _child_c">proto::_child_c<></a></code></span></dt> +<dd><p> + Given a non-terminal expression, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child_c</span><span class="special"><</span><em class="replaceable"><code>N</code></em><span class="special">></span></code> returns the <em class="replaceable"><code>N</code></em>-th + child. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="reference.html#boost.proto._child">proto::_child</a></code></span></dt> +<dd><p> + A synonym for <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child_c</span><span class="special"><</span><span class="number">0</span><span class="special">></span></code>. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="reference.html#boost.proto._left">proto::_left</a></code></span></dt> +<dd><p> + A synonym for <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child_c</span><span class="special"><</span><span class="number">0</span><span class="special">></span></code>. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="reference.html#boost.proto._right">proto::_right</a></code></span></dt> +<dd><p> + A synonym for <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child_c</span><span class="special"><</span><span class="number">1</span><span class="special">></span></code>. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_expr.html" title="Struct _expr">proto::_expr</a></code></span></dt> +<dd><p> + Returns the current expression unmodified. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_state.html" title="Struct _state">proto::_state</a></code></span></dt> +<dd><p> + Returns the current state unmodified. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_data.html" title="Struct _data">proto::_data</a></code></span></dt> +<dd><p> + Returns the current data unmodified. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/call.html" title="Struct template call">proto::call<></a></code></span></dt> +<dd><p> + For a given callable transform <code class="computeroutput"><em class="replaceable"><code>CT</code></em></code>, + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><em class="replaceable"><code>CT</code></em><span class="special">></span></code> turns the callable transform + into a primitive transform. This is useful for disambiguating callable + transforms from object transforms, and also for working around + compiler bugs with nested function types. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/make.html" title="Struct template make">proto::make<></a></code></span></dt> +<dd><p> + For a given object transform <code class="computeroutput"><em class="replaceable"><code>OT</code></em></code>, + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">make</span><span class="special"><</span><em class="replaceable"><code>OT</code></em><span class="special">></span></code> turns the object transform + into a primitive transform. This is useful for disambiguating object + transforms from callable transforms, and also for working around + compiler bugs with nested function types. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_default.html" title="Struct template _default">proto::_default<></a></code></span></dt> +<dd><p> + Given a grammar <em class="replaceable"><code>G</code></em>, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><em class="replaceable"><code>G</code></em><span class="special">></span></code> evaluates the current node + according to the standard C++ meaning of the operation the node + represents. For instance, if the current node is a binary plus + node, the two children will both be evaluated according to <code class="computeroutput"><em class="replaceable"><code>G</code></em></code> + and the results will be added and returned. The return type is + deduced with the help of the Boost.Typeof library. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/fold.html" title="Struct template fold">proto::fold<></a></code></span></dt> +<dd><p> + Given three transforms <code class="computeroutput"><em class="replaceable"><code>ET</code></em></code>, + <code class="computeroutput"><em class="replaceable"><code>ST</code></em></code>, and <code class="computeroutput"><em class="replaceable"><code>FT</code></em></code>, + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span><em class="replaceable"><code>ET</code></em><span class="special">,</span> <em class="replaceable"><code>ST</code></em><span class="special">,</span> <em class="replaceable"><code>FT</code></em><span class="special">></span></code> first evaluates <code class="computeroutput"><em class="replaceable"><code>ET</code></em></code> + to obtain a Fusion sequence and <code class="computeroutput"><em class="replaceable"><code>ST</code></em></code> + to obtain an initial state for the fold, and then evaluates <code class="computeroutput"><em class="replaceable"><code>FT</code></em></code> + for each element in the sequence to generate the next state from + the previous. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/reverse_fold.html" title="Struct template reverse_fold">proto::reverse_fold<></a></code></span></dt> +<dd><p> + Like <code class="computeroutput"><a class="link" href="../boost/proto/fold.html" title="Struct template fold">proto::fold<></a></code>, except the + elements in the Fusion sequence are iterated in reverse order. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/fold_tree.html" title="Struct template fold_tree">proto::fold_tree<></a></code></span></dt> +<dd><p> + Like <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span><em class="replaceable"><code>ET</code></em><span class="special">,</span> <em class="replaceable"><code>ST</code></em><span class="special">,</span> <em class="replaceable"><code>FT</code></em><span class="special">></span></code>, except that the result of + the <code class="computeroutput"><em class="replaceable"><code>ET</code></em></code> transform is treated + as an expression tree that is <span class="emphasis"><em>flattened</em></span> to + generate the sequence to be folded. Flattening an expression tree + causes child nodes with the same tag type as the parent to be put + into sequence. For instance, <code class="computeroutput"><span class="identifier">a</span> + <span class="special">>></span> <span class="identifier">b</span> + <span class="special">>></span> <span class="identifier">c</span></code> + would be flattened to the sequence [<code class="computeroutput"><span class="identifier">a</span></code>, + <code class="computeroutput"><span class="identifier">b</span></code>, <code class="computeroutput"><span class="identifier">c</span></code>], and this is the sequence + that would be folded. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/reverse_fold_tree.html" title="Struct template reverse_fold_tree">proto::reverse_fold_tree<></a></code></span></dt> +<dd><p> + Like <code class="computeroutput"><a class="link" href="../boost/proto/fold_tree.html" title="Struct template fold_tree">proto::fold_tree<></a></code>, except that + the flattened sequence is iterated in reverse order. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/lazy.html" title="Struct template lazy">proto::lazy<></a></code></span></dt> +<dd><p> + A combination of <code class="computeroutput"><a class="link" href="../boost/proto/make.html" title="Struct template make">proto::make<></a></code> + and <code class="computeroutput"><a class="link" href="../boost/proto/call.html" title="Struct template call">proto::call<></a></code> that is useful + when the nature of the transform depends on the expression, state + and/or data parameters. <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">lazy</span><span class="special"><</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">A0</span><span class="special">,</span><span class="identifier">A1</span><span class="special">...</span><span class="identifier">An</span><span class="special">)></span></code> first evaluates <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">make</span><span class="special"><</span><span class="identifier">R</span><span class="special">()></span></code> + to compute a callable type <code class="computeroutput"><span class="identifier">R2</span></code>. + Then, it evaluates <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><span class="identifier">R2</span><span class="special">(</span><span class="identifier">A0</span><span class="special">,</span><span class="identifier">A1</span><span class="special">...</span><span class="identifier">An</span><span class="special">)></span></code>. + </p></dd> +</dl> +</div> +<h6> +<a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.h0"></a> + <span><a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.all_grammars_are_primitive_transforms"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.canned_transforms.all_grammars_are_primitive_transforms">All + Grammars Are Primitive Transforms</a> + </h6> +<p> + In addition to the above primitive transforms, all of Proto's grammar + elements are also primitive transforms. Their behaviors are described + below. + </p> +<div class="variablelist"> +<p class="title"><b></b></p> +<dl> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/_.html" title="Struct _">proto::_</a></code></span></dt> +<dd><p> + Return the current expression unmodified. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code></span></dt> +<dd><p> + For the specified set of alternate sub-grammars, find the one that + matches the given expression and apply its associated transform. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/and_.html" title="Struct template and_">proto::and_<></a></code></span></dt> +<dd><p> + For the given set of sub-grammars, apply all the associated transforms + and return the result of the last. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/not_.html" title="Struct template not_">proto::not_<></a></code></span></dt> +<dd><p> + Return the current expression unmodified. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/if_.html" title="Struct template if_">proto::if_<></a></code></span></dt> +<dd><p> + Given three transforms, evaluate the first and treat the result + as a compile-time Boolean value. If it is true, evaluate the second + transform. Otherwise, evaluate the third. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/switch_.html" title="Struct template switch_">proto::switch_<></a></code></span></dt> +<dd><p> + As with <code class="computeroutput"><a class="link" href="../boost/proto/or_.html" title="Struct template or_">proto::or_<></a></code>, find the sub-grammar + that matches the given expression and apply its associated transform. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal<></a></code></span></dt> +<dd><p> + Return the current terminal expression unmodified. + </p></dd> +<dt><span class="term"> <code class="computeroutput"><a class="link" href="../boost/proto/plus.html" title="Struct template plus">proto::plus<></a></code>, <code class="computeroutput"><a class="link" href="../boost/proto/nary_expr.html" title="Struct template nary_expr">proto::nary_expr<></a></code>, + et. al.</span></dt> +<dd><p> + A Proto grammar that matches a non-terminal such as <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><em class="replaceable"><code>G0</code></em><span class="special">,</span> <em class="replaceable"><code>G1</code></em><span class="special">></span></code>, when used as a primitive transform, + creates a new plus node where the left child is transformed according + to <code class="computeroutput"><em class="replaceable"><code>G0</code></em></code> and the right child + with <code class="computeroutput"><em class="replaceable"><code>G1</code></em></code>. + </p></dd> +</dl> +</div> +<h6> +<a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.h1"></a> + <span><a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.the_pass_through_transform"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.canned_transforms.the_pass_through_transform">The + Pass-Through Transform</a> + </h6> +<p> + Note the primitive transform associated with grammar elements such as + <code class="computeroutput"><a class="link" href="../boost/proto/plus.html" title="Struct template plus">proto::plus<></a></code> described above. + They possess a so-called <span class="emphasis"><em>pass-through</em></span> transform. + The pass-through transform accepts an expression of a certain tag type + (say, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span></code>) and creates a new expression + of the same tag type, where each child expression is transformed according + to the corresponding child grammar of the pass-through transform. So + for instance this grammar ... + </p> +<pre class="programlisting"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> <span class="identifier">X</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">Y</span><span class="special">></span> <span class="special">></span> +</pre> +<p> + ... matches function expressions where the first child matches the <code class="computeroutput"><span class="identifier">X</span></code> grammar and the rest match the <code class="computeroutput"><span class="identifier">Y</span></code> grammar. When used as a transform, + the above grammar will create a new function expression where the first + child is transformed according to <code class="computeroutput"><span class="identifier">X</span></code> + and the rest are transformed according to <code class="computeroutput"><span class="identifier">Y</span></code>. + </p> +<p> + The following class templates in Proto can be used as grammars with pass-through + transforms: + </p> +<div class="table"> +<a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.t0"></a><p class="title"><b>Table 20.11. Class Templates With Pass-Through Transforms</b></p> +<div class="table-contents"><table class="table" summary="Class Templates With Pass-Through Transforms"> +<colgroup><col></colgroup> +<thead><tr><th> + <p> + Templates with Pass-Through Transforms + </p> + </th></tr></thead> +<tbody> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_plus</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">negate</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">dereference</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">complement</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">address_of</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_not</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pre_inc</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pre_dec</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">post_inc</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">post_dec</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">modulus</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">less</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">greater</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">less_equal</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">greater_equal</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">equal_to</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_equal_to</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_or</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_and</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_and</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_or</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_xor</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">comma</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">mem_ptr</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_left_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">shift_right_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">modulus_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_and_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_or_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">bitwise_xor_assign</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">subscript</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">if_else_</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_expr</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">binary_expr</span><span class="special"><></span></code> + </p> + </td></tr> +<tr><td> + <p> + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><></span></code> + </p> + </td></tr> +</tbody> +</table></div> +</div> +<br class="table-break"><h6> +<a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.h2"></a> + <span><a name="boost_proto.users_guide.back_end.expression_transformation.canned_transforms.the_many_roles_of_proto_operator_metafunctions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.canned_transforms.the_many_roles_of_proto_operator_metafunctions">The + Many Roles of Proto Operator Metafunctions</a> + </h6> +<p> + We've seen templates such as <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal<></a></code>, + <code class="computeroutput"><a class="link" href="../boost/proto/plus.html" title="Struct template plus">proto::plus<></a></code> and <code class="computeroutput"><a class="link" href="../boost/proto/nary_expr.html" title="Struct template nary_expr">proto::nary_expr<></a></code> + fill many roles. They are metafunction that generate expression types. + They are grammars that match expression types. And they are primitive + transforms. The following code samples show examples of each. + </p> +<p> + <span class="bold"><strong>As Metafunctions ...</strong></span> + </p> +<pre class="programlisting"><span class="comment">// proto::terminal<> and proto::plus<> are metafunctions</span> +<span class="comment">// that generate expression types:</span> +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">int_</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">int_</span><span class="special">,</span> <span class="identifier">int_</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">plus_</span><span class="special">;</span> + +<span class="identifier">int_</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">{</span><span class="number">42</span><span class="special">},</span> <span class="identifier">j</span> <span class="special">=</span> <span class="special">{</span><span class="number">24</span><span class="special">};</span> +<span class="identifier">plus_</span> <span class="identifier">p</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">};</span> +</pre> +<p> + <span class="bold"><strong>As Grammars ...</strong></span> + </p> +<pre class="programlisting"><span class="comment">// proto::terminal<> and proto::plus<> are grammars that</span> +<span class="comment">// match expression types</span> +<span class="keyword">struct</span> <span class="identifier">Int</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">{};</span> +<span class="keyword">struct</span> <span class="identifier">Plus</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Int</span><span class="special">,</span> <span class="identifier">Int</span><span class="special">></span> <span class="special">{};</span> + +<span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">int_</span><span class="special">,</span> <span class="identifier">Int</span> <span class="special">></span> <span class="special">));</span> +<span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span> <span class="identifier">plus_</span><span class="special">,</span> <span class="identifier">Plus</span> <span class="special">></span> <span class="special">));</span> +</pre> +<p> + <span class="bold"><strong>As Primitive Transforms ...</strong></span> + </p> +<pre class="programlisting"><span class="comment">// A transform that removes all unary_plus nodes in an expression</span> +<span class="keyword">struct</span> <span class="identifier">RemoveUnaryPlus</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">unary_plus</span><span class="special"><</span><span class="identifier">RemoveUnaryPlus</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">RemoveUnaryPlus</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child</span><span class="special">)</span> + <span class="special">></span> + <span class="comment">// Use proto::terminal<> and proto::nary_expr<></span> + <span class="comment">// both as grammars and as primitive transforms.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">RemoveUnaryPlus</span><span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">literal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">i</span><span class="special">(</span><span class="number">0</span><span class="special">);</span> + + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">display_expr</span><span class="special">(</span> + <span class="special">+</span><span class="identifier">i</span> <span class="special">-</span> <span class="special">+(</span><span class="identifier">i</span> <span class="special">-</span> <span class="special">+</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">);</span> + + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">display_expr</span><span class="special">(</span> + <span class="identifier">RemoveUnaryPlus</span><span class="special">()(</span> <span class="special">+</span><span class="identifier">i</span> <span class="special">-</span> <span class="special">+(</span><span class="identifier">i</span> <span class="special">-</span> <span class="special">+</span><span class="identifier">i</span><span class="special">)</span> <span class="special">)</span> + <span class="special">);</span> +<span class="special">}</span> +</pre> +<p> + The above code displays the following, which shows that unary plus nodes + have been stripped from the expression: + </p> +<pre class="programlisting">minus( + unary_plus( + terminal(0) + ) + , unary_plus( + minus( + terminal(0) + , unary_plus( + terminal(0) + ) + ) + ) +) +minus( + terminal(0) + , minus( + terminal(0) + , terminal(0) + ) +) +</pre> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.primitives"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.primitives" title="Building Custom Primitive Transforms">Building + Custom Primitive Transforms</a> +</h5></div></div></div> +<p> + In previous sections, we've seen how to compose larger transforms out + of smaller transforms using function types. The smaller transforms from + which larger transforms are composed are <span class="emphasis"><em>primitive transforms</em></span>, + and Proto provides a bunch of common ones such as <code class="computeroutput"><span class="identifier">_child0</span></code> + and <code class="computeroutput"><span class="identifier">_value</span></code>. In this section + we'll see how to author your own primitive transforms. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + There are a few reasons why you might want to write your own primitive + transforms. For instance, your transform may be complicated, and composing + it out of primitives becomes unwieldy. You might also need to work + around compiler bugs on legacy compilers that make composing transforms + using function types problematic. Finally, you might also decide to + define your own primitive transforms to improve compile times. Since + Proto can simply invoke a primitive transform directly without having + to process arguments or differentiate callable transforms from object + transforms, primitive transforms are more efficient. + </p></td></tr> +</table></div> +<p> + Primitive transforms inherit from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">transform</span><span class="special"><></span></code> and have a nested <code class="computeroutput"><span class="identifier">impl</span><span class="special"><></span></code> + template that inherits from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">transform_impl</span><span class="special"><></span></code>. For example, this is how Proto + defines the <code class="computeroutput"><span class="identifier">_child_c</span><span class="special"><</span><em class="replaceable"><code>N</code></em><span class="special">></span></code> + transform, which returns the <em class="replaceable"><code>N</code></em>-th child of + the current expression: + </p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">proto</span> +<span class="special">{</span> + <span class="comment">// A primitive transform that returns N-th child</span> + <span class="comment">// of the current expression.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">_child_c</span> <span class="special">:</span> <span class="identifier">transform</span><span class="special"><</span><span class="identifier">_child_c</span><span class="special"><</span><span class="identifier">N</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">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">State</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Data</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">impl</span> <span class="special">:</span> <span class="identifier">transform_impl</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">State</span><span class="special">,</span> <span class="identifier">Data</span><span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> + <span class="keyword">typename</span> <span class="identifier">result_of</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">N</span><span class="special">>::</span><span class="identifier">type</span> + <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span> + <span class="keyword">typename</span> <span class="identifier">impl</span><span class="special">::</span><span class="identifier">expr_param</span> <span class="identifier">expr</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">impl</span><span class="special">::</span><span class="identifier">state_param</span> <span class="identifier">state</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">impl</span><span class="special">::</span><span class="identifier">data_param</span> <span class="identifier">data</span> + <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">child_c</span><span class="special"><</span><span class="identifier">N</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">);</span> + <span class="special">}</span> + <span class="special">};</span> + <span class="special">};</span> + + <span class="comment">// Note that _child_c<N> is callable, so that</span> + <span class="comment">// it can be used in callable transforms, as:</span> + <span class="comment">// _child_c<0>(_child_c<1>)</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">N</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">is_callable</span><span class="special"><</span><span class="identifier">_child_c</span><span class="special"><</span><span class="identifier">N</span><span class="special">></span> <span class="special">></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> + The <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">transform</span><span class="special"><></span></code> + base class provides the <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> overloads and the nested <code class="computeroutput"><span class="identifier">result</span><span class="special"><></span></code> + template that make your transform a valid function object. These are + implemented in terms of the nested <code class="computeroutput"><span class="identifier">impl</span><span class="special"><></span></code> template you define. + </p> +<p> + The <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">transform_impl</span><span class="special"><></span></code> + base class is a convenience. It provides some nested typedefs that are + generally useful. They are specified in the table below: + </p> +<div class="table"> +<a name="boost_proto.users_guide.back_end.expression_transformation.primitives.t0"></a><p class="title"><b>Table 20.12. proto::transform_impl<Expr, State, Data> typedefs</b></p> +<div class="table-contents"><table class="table" summary="proto::transform_impl<Expr, State, Data> typedefs"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + typedef + </p> + </th> +<th> + <p> + Equivalent To + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">expr</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">state</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">State</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">data</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">Data</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">expr_param</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">add_reference</span><span class="special"><</span><span class="keyword">typename</span> + <span class="identifier">add_const</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">state_param</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">add_reference</span><span class="special"><</span><span class="keyword">typename</span> + <span class="identifier">add_const</span><span class="special"><</span><span class="identifier">State</span><span class="special">>::</span><span class="identifier">type</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +</tr> +<tr> +<td> + <p> + <code class="computeroutput"><span class="identifier">data_param</span></code> + </p> + </td> +<td> + <p> + <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">add_reference</span><span class="special"><</span><span class="keyword">typename</span> + <span class="identifier">add_const</span><span class="special"><</span><span class="identifier">Data</span><span class="special">>::</span><span class="identifier">type</span><span class="special">>::</span><span class="identifier">type</span></code> + </p> + </td> +</tr> +</tbody> +</table></div> +</div> +<br class="table-break"><p> + You'll notice that <code class="computeroutput"><span class="identifier">_child_c</span><span class="special">::</span><span class="identifier">impl</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> takes arguments of types <code class="computeroutput"><span class="identifier">expr_param</span></code>, <code class="computeroutput"><span class="identifier">state_param</span></code>, + and <code class="computeroutput"><span class="identifier">data_param</span></code>. The typedefs + make it easy to accept arguments by reference or const reference accordingly. + </p> +<p> + The only other interesting bit is the <code class="computeroutput"><span class="identifier">is_callable</span><span class="special"><></span></code> specialization, which will be + described in the <a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.is_callable" title="Making Your Transform Callable">next + section</a>. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="boost_proto.users_guide.back_end.expression_transformation.is_callable"></a><a class="link" href="users_guide.html#boost_proto.users_guide.back_end.expression_transformation.is_callable" title="Making Your Transform Callable">Making + Your Transform Callable</a> +</h5></div></div></div> +<p> + Transforms are typically of the form <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">Something</span><span class="special">,</span> <span class="identifier">R</span><span class="special">(</span><span class="identifier">A0</span><span class="special">,</span><span class="identifier">A1</span><span class="special">,...)</span> <span class="special">></span></code>. + The question is whether <code class="computeroutput"><span class="identifier">R</span></code> + represents a function to call or an object to construct, and the answer + determines how <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a></code> evaluates the transform. + <code class="computeroutput"><a class="link" href="../boost/proto/when.html" title="Struct template when">proto::when<></a></code> uses the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_callable</span><span class="special"><></span></code> + trait to disambiguate between the two. Proto does its best to guess whether + a type is callable or not, but it doesn't always get it right. It's best + to know the rules Proto uses, so that you know when you need to be more + explicit. + </p> +<p> + For most types <code class="computeroutput"><span class="identifier">R</span></code>, <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_callable</span><span class="special"><</span><span class="identifier">R</span><span class="special">></span></code> + checks for inheritance from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span></code>. + However, if the type <code class="computeroutput"><span class="identifier">R</span></code> + is a template specialization, Proto assumes that it is <span class="emphasis"><em>not</em></span> + callable <span class="emphasis"><em>even if the template inherits from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span></code></em></span>. + We'll see why in a minute. Consider the following erroneous callable + object: + </p> +<pre class="programlisting"><span class="comment">// Proto can't tell this defines something callable!</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">times2</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">T</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">i</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// ERROR! This is not going to multiply the int by 2:</span> +<span class="keyword">struct</span> <span class="identifier">IntTimes2</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + The problem is that Proto doesn't know that <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> is callable, so rather that invoking + the <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> + function object, Proto will try to construct a <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> object and initialize it will an + <code class="computeroutput"><span class="keyword">int</span></code>. That will not compile. + </p> +<div class="note"><table border="0" summary="Note"> +<tr> +<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> +<th align="left">Note</th> +</tr> +<tr><td align="left" valign="top"><p> + Why can't Proto tell that <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> is callable? After all, it inherits + from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span></code>, and that is detectable, + right? The problem is that merely asking whether some type <code class="computeroutput"><span class="identifier">X</span><span class="special"><</span><span class="identifier">Y</span><span class="special">></span></code> + inherits from <code class="computeroutput"><span class="identifier">callable</span></code> + will cause the template <code class="computeroutput"><span class="identifier">X</span><span class="special"><</span><span class="identifier">Y</span><span class="special">></span></code> to be instantiated. That's a problem + for a type like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">_value</span><span class="special">(</span><span class="identifier">_child1</span><span class="special">)></span></code>. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><></span></code> will not suffer to be instantiated + with <code class="computeroutput"><span class="identifier">_value</span><span class="special">(</span><span class="identifier">_child1</span><span class="special">)</span></code> + as a template parameter. Since merely asking the question will sometimes + result in a hard error, Proto can't ask; it has to assume that <code class="computeroutput"><span class="identifier">X</span><span class="special"><</span><span class="identifier">Y</span><span class="special">></span></code> + represents an object to construct and not a function to call. + </p></td></tr> +</table></div> +<p> + There are a couple of solutions to the <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> problem. One solution is to wrap + the transform in <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><></span></code>. This forces Proto to treat + <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code> + as callable: + </p> +<pre class="programlisting"><span class="comment">// OK, calls times2<int></span> +<span class="keyword">struct</span> <span class="identifier">IntTimes2</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)></span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + This can be a bit of a pain, because we need to wrap every use of <code class="computeroutput"><span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>, + which can be tedious and error prone, and makes our grammar cluttered + and harder to read. + </p> +<p> + Another solution is to specialize <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_callable</span><span class="special"><></span></code> on our <code class="computeroutput"><span class="identifier">times2</span><span class="special"><></span></code> template: + </p> +<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">proto</span> +<span class="special">{</span> + <span class="comment">// Tell Proto that times2<> is callable</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">is_callable</span><span class="special"><</span><span class="identifier">times2</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">></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> + +<span class="comment">// OK, times2<> is callable</span> +<span class="keyword">struct</span> <span class="identifier">IntTimes2</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + This is better, but still a pain because of the need to open Proto's + namespace. + </p> +<p> + You could simply make sure that the callable type is not a template specialization. + Consider the following: + </p> +<pre class="programlisting"><span class="comment">// No longer a template specialization!</span> +<span class="keyword">struct</span> <span class="identifier">times2int</span> <span class="special">:</span> <span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">{};</span> + +<span class="comment">// OK, times2int is callable</span> +<span class="keyword">struct</span> <span class="identifier">IntTimes2</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">times2int</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + This works because now Proto can tell that <code class="computeroutput"><span class="identifier">times2int</span></code> + inherits (indirectly) from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span></code>. + Any non-template types can be safely checked for inheritance because, + as they are not templates, there is no worry about instantiation errors. + </p> +<p> + There is one last way to tell Proto that <code class="computeroutput"><span class="identifier">times2</span><span class="special"><></span></code> is callable. You could add an + extra dummy template parameter that defaults to <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span></code>: + </p> +<pre class="programlisting"><span class="comment">// Proto will recognize this as callable</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">typename</span> <span class="identifier">Callable</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">times2</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">T</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">i</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// OK, this works!</span> +<span class="keyword">struct</span> <span class="identifier">IntTimes2</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">times2</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> +<span class="special">{};</span> +</pre> +<p> + Note that in addition to the extra template parameter, <code class="computeroutput"><span class="identifier">times2</span><span class="special"><></span></code> + still inherits from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span></code>. + That's not necessary in this example but it is good style because any + types derived from <code class="computeroutput"><span class="identifier">times2</span><span class="special"><></span></code> (as <code class="computeroutput"><span class="identifier">times2int</span></code> + defined above) will still be considered callable. + </p> +</div> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.examples"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples" title="Examples">Examples</a> +</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.hello_world">Hello + World: Building an Expression Template and Evaluating It</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.calc1">Calc1: Defining + an Evaluation Context</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.calc2">Calc2: Adding + Members Using <code class="literal">proto::extends<></code></a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.calc3">Calc3: Defining + a Simple Transform</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.lazy_vector">Lazy + Vector: Controlling Operator Overloads</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.rgb">RGB: Type Manipulations + with Proto Transforms</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.tarray">TArray: A + Simple Linear Algebra Library</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.vec3">Vec3: Computing + With Transforms and Contexts</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.vector">Vector: Adapting + a Non-Proto Terminal Type</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.mixed">Mixed: Adapting + Several Non-Proto Terminal Types</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.map_assign">Map Assign: + An Intermediate Transform</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.future_group">Future + Group: A More Advanced Transform</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.lambda">Lambda: A + Simple Lambda Library with Proto</a></span></dt> +<dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples.checked_calc">Checked + Calculator: A Simple Example of External Transforms</a></span></dt> +</dl></div> +<p> + A code example is worth a thousand words ... + </p> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.hello_world"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.hello_world" title="Hello World: Building an Expression Template and Evaluating It">Hello + World: Building an Expression Template and Evaluating It</a> +</h4></div></div></div> +<p> + A trivial example which builds and expression template and evaluates it. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="comment">// This #include is only needed for compilers that use typeof emulation:</span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> + +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">};</span> + +<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">)</span> +<span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_context</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special"><<</span> <span class="string">"hello"</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="string">" world"</span> <span class="special">);</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.calc1"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.calc1" title="Calc1: Defining an Evaluation Context">Calc1: Defining + an Evaluation Context</a> +</h4></div></div></div> +<p> + A simple example that builds a miniature embedded domain-specific language + for lazy arithmetic expressions, with TR1 bind-style argument placeholders. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is a simple example of how to build an arithmetic expression</span> +<span class="comment">// evaluator with placeholders.</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">placeholder</span> <span class="special">{};</span> + +<span class="comment">// Define some placeholders</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span> <span class="number">1</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> +<span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span> <span class="number">2</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_2</span> <span class="special">=</span> <span class="special">{{}};</span> + +<span class="comment">// Define a calculator context, for evaluating arithmetic expressions</span> +<span class="keyword">struct</span> <span class="identifier">calculator_context</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// The values bound to the placeholders</span> + <span class="keyword">double</span> <span class="identifier">d</span><span class="special">[</span><span class="number">2</span><span class="special">];</span> + + <span class="comment">// The result of evaluating arithmetic expressions</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">explicit</span> <span class="identifier">calculator_context</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">d</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">d1</span><span class="special">;</span> + <span class="identifier">d</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">d2</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Handle the evaluation of the placeholder terminals</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">>)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">d</span><span class="special">[</span> <span class="identifier">I</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">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">double</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.</span> <span class="special">)</span> +<span class="special">{</span> + <span class="comment">// Create a calculator context with d1 and d2 substituted for _1 and _2</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span> <span class="identifier">d2</span><span class="special">);</span> + + <span class="comment">// Evaluate the calculator expression with the calculator_context</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Displays "5"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">_1</span> <span class="special">+</span> <span class="number">2.0</span><span class="special">,</span> <span class="number">3.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Displays "6"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">_1</span> <span class="special">*</span> <span class="identifier">_2</span><span class="special">,</span> <span class="number">3.0</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Displays "0.5"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="special">(</span><span class="identifier">_1</span> <span class="special">-</span> <span class="identifier">_2</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span><span class="special">,</span> <span class="number">3.0</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.calc2"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.calc2" title="Calc2: Adding Members Using proto::extends<>">Calc2: Adding + Members Using <code class="literal">proto::extends<></code></a> +</h4></div></div></div> +<p> + An extension of the Calc1 example that uses <code class="computeroutput"><a class="link" href="../boost/proto/extends.html" title="Struct template extends">proto::extends<></a></code> + to make calculator expressions valid function objects that can be used + with STL algorithms. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This example enhances the simple arithmetic expression evaluator</span> +<span class="comment">// in calc1.cpp by using proto::extends to make arithmetic</span> +<span class="comment">// expressions immediately evaluable with operator (), a-la a</span> +<span class="comment">// function object</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator_expression</span><span class="special">;</span> + +<span class="comment">// Tell proto how to generate expressions in the calculator_domain</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">calculator_expression</span><span class="special">></span> <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Will be used to define the placeholders _1 and _2</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">placeholder</span> <span class="special">{};</span> + +<span class="comment">// Define a calculator context, for evaluating arithmetic expressions</span> +<span class="comment">// (This is as before, in calc1.cpp)</span> +<span class="keyword">struct</span> <span class="identifier">calculator_context</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// The values bound to the placeholders</span> + <span class="keyword">double</span> <span class="identifier">d</span><span class="special">[</span><span class="number">2</span><span class="special">];</span> + + <span class="comment">// The result of evaluating arithmetic expressions</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">explicit</span> <span class="identifier">calculator_context</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">d</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">d1</span><span class="special">;</span> + <span class="identifier">d</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">d2</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Handle the evaluation of the placeholder terminals</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">>)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">d</span><span class="special">[</span> <span class="identifier">I</span> <span class="special">-</span> <span class="number">1</span> <span class="special">];</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Wrap all calculator expressions in this type, which defines</span> +<span class="comment">// operator () to evaluate the expression.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator_expression</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">explicit</span> <span class="identifier">calculator_expression</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">calculator_expression</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="identifier">BOOST_PROTO_EXTENDS_USING_ASSIGN</span><span class="special">(</span><span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>)</span> + + <span class="comment">// Override operator () to evaluate the expression</span> + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="keyword">double</span> <span class="identifier">d1</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">d1</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="keyword">double</span> <span class="identifier">d1</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span> <span class="identifier">d2</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Define some placeholders (notice they're wrapped in calculator_expression<>)</span> +<span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span> <span class="number">1</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_1</span><span class="special">;</span> +<span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span> <span class="number">2</span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_2</span><span class="special">;</span> + +<span class="comment">// Now, our arithmetic expressions are immediately executable function objects:</span> +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Displays "5"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="number">2.0</span><span class="special">)(</span> <span class="number">3.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Displays "6"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span> <span class="identifier">_1</span> <span class="special">*</span> <span class="identifier">_2</span> <span class="special">)(</span> <span class="number">3.0</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Displays "0.5"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">_1</span> <span class="special">-</span> <span class="identifier">_2</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">)(</span> <span class="number">3.0</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.calc3"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.calc3" title="Calc3: Defining a Simple Transform">Calc3: Defining + a Simple Transform</a> +</h4></div></div></div> +<p> + An extension of the Calc2 example that uses a Proto transform to calculate + the arity of a calculator expression and statically assert that the correct + number of arguments are passed. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This example enhances the arithmetic expression evaluator</span> +<span class="comment">// in calc2.cpp by using a proto transform to calculate the</span> +<span class="comment">// number of arguments an expression requires and using a</span> +<span class="comment">// compile-time assert to guarantee that the right number of</span> +<span class="comment">// arguments are actually specified.</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">mpl</span><span class="special">/</span><span class="keyword">int</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">mpl</span><span class="special">/</span><span class="identifier">assert</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">mpl</span><span class="special">/</span><span class="identifier">min_max</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</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">proto</span><span class="special">/</span><span class="identifier">transform</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="comment">// Will be used to define the placeholders _1 and _2</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">placeholder</span> <span class="special">:</span> <span class="identifier">I</span> <span class="special">{};</span> + +<span class="comment">// This grammar basically says that a calculator expression is one of:</span> +<span class="comment">// - A placeholder terminal</span> +<span class="comment">// - Some other terminal</span> +<span class="comment">// - Some non-terminal whose children are calculator expressions</span> +<span class="comment">// In addition, it has transforms that say how to calculate the</span> +<span class="comment">// expression arity for each of the three cases.</span> +<span class="keyword">struct</span> <span class="identifier">CalculatorGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + + <span class="comment">// placeholders have a non-zero arity ...</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> <span class="special">></span> + + <span class="comment">// Any other terminals have arity 0 ...</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</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="number">0</span><span class="special">>()</span> <span class="special">></span> + + <span class="comment">// For any non-terminals, find the arity of the children and</span> + <span class="comment">// take the maximum. This is recursive.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span><span class="identifier">_</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="number">0</span><span class="special">>(),</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><</span><span class="identifier">CalculatorGrammar</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">>()</span> <span class="special">></span> <span class="special">></span> + + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Simple wrapper for calculating a calculator expression's arity.</span> +<span class="comment">// It specifies mpl::int_<0> as the initial state. The data, which</span> +<span class="comment">// is not used, is mpl::void_.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator_arity</span> + <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">CalculatorGrammar</span><span class="special">(</span><span class="identifier">Expr</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">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator_expression</span><span class="special">;</span> + +<span class="comment">// Tell proto how to generate expressions in the calculator_domain</span> +<span class="keyword">struct</span> <span class="identifier">calculator_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">calculator_expression</span><span class="special">></span> <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Define a calculator context, for evaluating arithmetic expressions</span> +<span class="comment">// (This is as before, in calc1.cpp and calc2.cpp)</span> +<span class="keyword">struct</span> <span class="identifier">calculator_context</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="comment">// The values bound to the placeholders</span> + <span class="keyword">double</span> <span class="identifier">d</span><span class="special">[</span><span class="number">2</span><span class="special">];</span> + + <span class="comment">// The result of evaluating arithmetic expressions</span> + <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">explicit</span> <span class="identifier">calculator_context</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="number">0.</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span> <span class="special">=</span> <span class="number">0.</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">d</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">d1</span><span class="special">;</span> + <span class="identifier">d</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">d2</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Handle the evaluation of the placeholder terminals</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">>)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">d</span><span class="special">[</span> <span class="identifier">I</span><span class="special">()</span> <span class="special">-</span> <span class="number">1</span> <span class="special">];</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Wrap all calculator expressions in this type, which defines</span> +<span class="comment">// operator () to evaluate the expression.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calculator_expression</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">calculator_domain</span><span class="special">></span> + <span class="identifier">base_type</span><span class="special">;</span> + + <span class="keyword">explicit</span> <span class="identifier">calculator_expression</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="identifier">BOOST_PROTO_EXTENDS_USING_ASSIGN</span><span class="special">(</span><span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>)</span> + + <span class="comment">// Override operator () to evaluate the expression</span> + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="comment">// Assert that the expression has arity 0</span> + <span class="identifier">BOOST_MPL_ASSERT_RELATION</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">==,</span> <span class="identifier">calculator_arity</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="keyword">double</span> <span class="identifier">d1</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="comment">// Assert that the expression has arity 1</span> + <span class="identifier">BOOST_MPL_ASSERT_RELATION</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="special">==,</span> <span class="identifier">calculator_arity</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">d1</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="keyword">double</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="keyword">double</span> <span class="identifier">d1</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">d2</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="comment">// Assert that the expression has arity 2</span> + <span class="identifier">BOOST_MPL_ASSERT_RELATION</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="special">==,</span> <span class="identifier">calculator_arity</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span> + <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">d1</span><span class="special">,</span> <span class="identifier">d2</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Define some placeholders (notice they're wrapped in calculator_expression<>)</span> +<span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</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="number">1</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_1</span><span class="special">;</span> +<span class="identifier">calculator_expression</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</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="number">2</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_2</span><span class="special">;</span> + +<span class="comment">// Now, our arithmetic expressions are immediately executable function objects:</span> +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Displays "5"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="number">2.0</span><span class="special">)(</span> <span class="number">3.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Displays "6"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span> <span class="identifier">_1</span> <span class="special">*</span> <span class="identifier">_2</span> <span class="special">)(</span> <span class="number">3.0</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Displays "0.5"</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">_1</span> <span class="special">-</span> <span class="identifier">_2</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">)(</span> <span class="number">3.0</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// This won't compile because the arity of the</span> + <span class="comment">// expression doesn't match the number of arguments</span> + <span class="comment">// ( (_1 - _2) / _2 )( 3.0 );</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.lazy_vector"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.lazy_vector" title="Lazy Vector: Controlling Operator Overloads">Lazy + Vector: Controlling Operator Overloads</a> +</h4></div></div></div> +<p> + This example constructs a mini-library for linear algebra, using expression + templates to eliminate the need for temporaries when adding vectors of + numbers. + </p> +<p> + This example uses a domain with a grammar to prune the set of overloaded + operators. Only those operators that produce valid lazy vector expressions + are allowed. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This example constructs a mini-library for linear algebra, using</span> +<span class="comment">// expression templates to eliminate the need for temporaries when</span> +<span class="comment">// adding vectors of numbers.</span> +<span class="comment">//</span> +<span class="comment">// This example uses a domain with a grammar to prune the set</span> +<span class="comment">// of overloaded operators. Only those operators that produce</span> +<span class="comment">// valid lazy vector expressions are allowed.</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">mpl</span><span class="special">/</span><span class="keyword">int</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">lazy_vector_expr</span><span class="special">;</span> + +<span class="comment">// This grammar describes which lazy vector expressions</span> +<span class="comment">// are allowed; namely, vector terminals and addition</span> +<span class="comment">// and subtraction of lazy vector expressions.</span> +<span class="keyword">struct</span> <span class="identifier">LazyVectorGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span> <span class="identifier">LazyVectorGrammar</span><span class="special">,</span> <span class="identifier">LazyVectorGrammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span> <span class="identifier">LazyVectorGrammar</span><span class="special">,</span> <span class="identifier">LazyVectorGrammar</span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Tell proto that in the lazy_vector_domain, all</span> +<span class="comment">// expressions should be wrapped in laxy_vector_expr<></span> +<span class="comment">// and must conform to the lazy vector grammar.</span> +<span class="keyword">struct</span> <span class="identifier">lazy_vector_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">lazy_vector_expr</span><span class="special">>,</span> <span class="identifier">LazyVectorGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here is an evaluation context that indexes into a lazy vector</span> +<span class="comment">// expression, and combines the result.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Size</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">lazy_subscript_context</span> +<span class="special">{</span> + <span class="identifier">lazy_subscript_context</span><span class="special">(</span><span class="identifier">Size</span> <span class="identifier">subscript</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">subscript_</span><span class="special">(</span><span class="identifier">subscript</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Use default_eval for all the operations ...</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">::</span><span class="identifier">proto_tag</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">lazy_subscript_context</span><span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// ... except for terminals, which we index with our subscript</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">lazy_subscript_context</span> <span class="special">&</span> <span class="identifier">ctx</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span> <span class="identifier">expr</span> <span class="special">)[</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">subscript_</span> <span class="special">];</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="identifier">Size</span> <span class="identifier">subscript_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// Here is the domain-specific expression wrapper, which overrides</span> +<span class="comment">// operator [] to evaluate the expression using the lazy_subscript_context.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">lazy_vector_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">lazy_vector_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">lazy_vector_expr</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">()</span> <span class="special">)</span> + <span class="special">:</span> <span class="identifier">lazy_vector_expr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span> <span class="identifier">expr</span> <span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Use the lazy_subscript_context<> to implement subscripting</span> + <span class="comment">// of a lazy vector expression tree.</span> + <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Size</span> <span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">lazy_subscript_context</span><span class="special"><</span><span class="identifier">Size</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">[](</span> <span class="identifier">Size</span> <span class="identifier">subscript</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">lazy_subscript_context</span><span class="special"><</span><span class="identifier">Size</span><span class="special">></span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">subscript</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Here is our lazy_vector terminal, implemented in terms of lazy_vector_expr</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">lazy_vector</span> + <span class="special">:</span> <span class="identifier">lazy_vector_expr</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">expr_type</span><span class="special">;</span> + + <span class="identifier">lazy_vector</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">T</span><span class="special">()</span> <span class="special">)</span> + <span class="special">:</span> <span class="identifier">lazy_vector_expr</span><span class="special"><</span><span class="identifier">expr_type</span><span class="special">>(</span> <span class="identifier">expr_type</span><span class="special">::</span><span class="identifier">make</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">value</span> <span class="special">)</span> <span class="special">)</span> <span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Here we define a += operator for lazy vector terminals that</span> + <span class="comment">// takes a lazy vector expression and indexes it. expr[i] here</span> + <span class="comment">// uses lazy_subscript_context<> under the covers.</span> + <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> + <span class="identifier">lazy_vector</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">).</span><span class="identifier">size</span><span class="special">();</span> + <span class="keyword">for</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">size</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">+=</span> <span class="identifier">expr</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="special">*</span><span class="keyword">this</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// lazy_vectors with 4 elements each.</span> + <span class="identifier">lazy_vector</span><span class="special"><</span> <span class="keyword">double</span> <span class="special">></span> <span class="identifier">v1</span><span class="special">(</span> <span class="number">4</span><span class="special">,</span> <span class="number">1.0</span> <span class="special">),</span> <span class="identifier">v2</span><span class="special">(</span> <span class="number">4</span><span class="special">,</span> <span class="number">2.0</span> <span class="special">),</span> <span class="identifier">v3</span><span class="special">(</span> <span class="number">4</span><span class="special">,</span> <span class="number">3.0</span> <span class="special">);</span> + + <span class="comment">// Add two vectors lazily and get the 2nd element.</span> + <span class="keyword">double</span> <span class="identifier">d1</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">v2</span> <span class="special">+</span> <span class="identifier">v3</span> <span class="special">)[</span> <span class="number">2</span> <span class="special">];</span> <span class="comment">// Look ma, no temporaries!</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">d1</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// Subtract two vectors and add the result to a third vector.</span> + <span class="identifier">v1</span> <span class="special">+=</span> <span class="identifier">v2</span> <span class="special">-</span> <span class="identifier">v3</span><span class="special">;</span> <span class="comment">// Still no temporaries!</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> + <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special"><<</span> <span class="char">'}'</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="comment">// This expression is disallowed because it does not conform</span> + <span class="comment">// to the LazyVectorGrammar</span> + <span class="comment">//(v2 + v3) += v1;</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.rgb"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.rgb" title="RGB: Type Manipulations with Proto Transforms">RGB: Type Manipulations + with Proto Transforms</a> +</h4></div></div></div> +<p> + This is a simple example of doing arbitrary type manipulations with Proto + transforms. It takes some expression involving primary colors and combines + the colors according to arbitrary rules. It is a port of the RGB example + from <a href="http://www.codesourcery.com/pooma/download.html" target="_top">PETE</a>. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is a simple example of doing arbitrary type manipulations with proto</span> +<span class="comment">// transforms. It takes some expression involving primary colors and combines</span> +<span class="comment">// the colors according to arbitrary rules. It is a port of the RGB example</span> +<span class="comment">// from PETE (http://www.codesourcery.com/pooma/download.html).</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">transform</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">RedTag</span> +<span class="special">{</span> + <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">sout</span><span class="special">,</span> <span class="identifier">RedTag</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">sout</span> <span class="special"><<</span> <span class="string">"This expression is red."</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">struct</span> <span class="identifier">BlueTag</span> +<span class="special">{</span> + <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">sout</span><span class="special">,</span> <span class="identifier">BlueTag</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">sout</span> <span class="special"><<</span> <span class="string">"This expression is blue."</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">struct</span> <span class="identifier">GreenTag</span> +<span class="special">{</span> + <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">sout</span><span class="special">,</span> <span class="identifier">GreenTag</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">sout</span> <span class="special"><<</span> <span class="string">"This expression is green."</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">RedTag</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">RedT</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">BlueTag</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">BlueT</span><span class="special">;</span> +<span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">GreenTag</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">GreenT</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">Red</span><span class="special">;</span> +<span class="keyword">struct</span> <span class="identifier">Blue</span><span class="special">;</span> +<span class="keyword">struct</span> <span class="identifier">Green</span><span class="special">;</span> + +<span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// A transform that produces new colors according to some arbitrary rules:</span> +<span class="comment">// red & green give blue, red & blue give green, blue and green give red.</span> +<span class="keyword">struct</span> <span class="identifier">Red</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Green</span><span class="special">,</span> <span class="identifier">Blue</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Blue</span><span class="special">,</span> <span class="identifier">Green</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Red</span><span class="special">,</span> <span class="identifier">Red</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">RedTag</span><span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Green</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Red</span><span class="special">,</span> <span class="identifier">Blue</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Blue</span><span class="special">,</span> <span class="identifier">Red</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Green</span><span class="special">,</span> <span class="identifier">Green</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">GreenTag</span><span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">Blue</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Red</span><span class="special">,</span> <span class="identifier">Green</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Green</span><span class="special">,</span> <span class="identifier">Red</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">Blue</span><span class="special">,</span> <span class="identifier">Blue</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">BlueTag</span><span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">RGB</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">Red</span><span class="special">,</span> <span class="identifier">RedTag</span><span class="special">()</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">Blue</span><span class="special">,</span> <span class="identifier">BlueTag</span><span class="special">()</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">Green</span><span class="special">,</span> <span class="identifier">GreenTag</span><span class="special">()</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">Expr</span><span class="special">></span> +<span class="keyword">void</span> <span class="identifier">printColor</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> +<span class="special">{</span> + <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// dummy state and data parameter, not used</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">RGB</span><span class="special">()(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">i</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">printColor</span><span class="special">(</span><span class="identifier">RedT</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">GreenT</span><span class="special">());</span> + <span class="identifier">printColor</span><span class="special">(</span><span class="identifier">RedT</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">GreenT</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">BlueT</span><span class="special">());</span> + <span class="identifier">printColor</span><span class="special">(</span><span class="identifier">RedT</span><span class="special">()</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">GreenT</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">BlueT</span><span class="special">()));</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.tarray"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.tarray" title="TArray: A Simple Linear Algebra Library">TArray: A + Simple Linear Algebra Library</a> +</h4></div></div></div> +<p> + This example constructs a mini-library for linear algebra, using expression + templates to eliminate the need for temporaries when adding arrays of numbers. + It duplicates the TArray example from <a href="http://www.codesourcery.com/pooma/download.html" target="_top">PETE</a>. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This example constructs a mini-library for linear algebra, using</span> +<span class="comment">// expression templates to eliminate the need for temporaries when</span> +<span class="comment">// adding arrays of numbers. It duplicates the TArray example from</span> +<span class="comment">// PETE (http://www.codesourcery.com/pooma/download.html)</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">mpl</span><span class="special">/</span><span class="keyword">int</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="comment">// This grammar describes which TArray expressions</span> +<span class="comment">// are allowed; namely, int and array terminals</span> +<span class="comment">// plus, minus, multiplies and divides of TArray expressions.</span> +<span class="keyword">struct</span> <span class="identifier">TArrayGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">int</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span> <span class="identifier">TArrayGrammar</span><span class="special">,</span> <span class="identifier">TArrayGrammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span> <span class="identifier">TArrayGrammar</span><span class="special">,</span> <span class="identifier">TArrayGrammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span> <span class="identifier">TArrayGrammar</span><span class="special">,</span> <span class="identifier">TArrayGrammar</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span> <span class="identifier">TArrayGrammar</span><span class="special">,</span> <span class="identifier">TArrayGrammar</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">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">TArrayExpr</span><span class="special">;</span> + +<span class="comment">// Tell proto that in the TArrayDomain, all</span> +<span class="comment">// expressions should be wrapped in TArrayExpr<> and</span> +<span class="comment">// must conform to the TArrayGrammar</span> +<span class="keyword">struct</span> <span class="identifier">TArrayDomain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">TArrayExpr</span><span class="special">>,</span> <span class="identifier">TArrayGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here is an evaluation context that indexes into a TArray</span> +<span class="comment">// expression, and combines the result.</span> +<span class="keyword">struct</span> <span class="identifier">TArraySubscriptCtx</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">TArraySubscriptCtx</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">TArraySubscriptCtx</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">i_</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Index array terminals with our subscript. Everything</span> + <span class="comment">// else will be handled by the default evaluation context.</span> + <span class="keyword">int</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">(&</span><span class="identifier">data</span><span class="special">)[</span><span class="number">3</span><span class="special">])</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">data</span><span class="special">[</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">i_</span><span class="special">];</span> + <span class="special">}</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// Here is an evaluation context that prints a TArray expression.</span> +<span class="keyword">struct</span> <span class="identifier">TArrayPrintCtx</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">TArrayPrintCtx</span> <span class="keyword">const</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">ostream</span> <span class="special">&</span><span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">TArrayPrintCtx</span><span class="special">()</span> <span class="special">{}</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">i</span><span class="special">;</span> + <span class="special">}</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">(&</span><span class="identifier">arr</span><span class="special">)[</span><span class="number">3</span><span class="special">])</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">arr</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="identifier">arr</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="identifier">arr</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special"><<</span> <span class="char">'}'</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">L</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">R</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">L</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">l</span><span class="special">,</span> <span class="identifier">R</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">r</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">l</span> <span class="special"><<</span> <span class="string">" + "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="char">')'</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">L</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">R</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">L</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">l</span><span class="special">,</span> <span class="identifier">R</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">r</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="char">'('</span> <span class="special"><<</span> <span class="identifier">l</span> <span class="special"><<</span> <span class="string">" - "</span> <span class="special"><<</span> <span class="identifier">r</span> <span class="special"><<</span> <span class="char">')'</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">L</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">R</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">L</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">l</span><span class="special">,</span> <span class="identifier">R</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">r</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">l</span> <span class="special"><<</span> <span class="string">" * "</span> <span class="special"><<</span> <span class="identifier">r</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">L</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">R</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">divides</span><span class="special">,</span> <span class="identifier">L</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">l</span><span class="special">,</span> <span class="identifier">R</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">r</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">l</span> <span class="special"><<</span> <span class="string">" / "</span> <span class="special"><<</span> <span class="identifier">r</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Here is the domain-specific expression wrapper, which overrides</span> +<span class="comment">// operator [] to evaluate the expression using the TArraySubscriptCtx.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">TArrayExpr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">TArrayExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">TArrayDomain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">TArrayExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">TArrayDomain</span><span class="special">></span> <span class="identifier">base_type</span><span class="special">;</span> + + <span class="identifier">TArrayExpr</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">()</span> <span class="special">)</span> + <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span> <span class="identifier">expr</span> <span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Use the TArraySubscriptCtx to implement subscripting</span> + <span class="comment">// of a TArray expression tree.</span> + <span class="keyword">int</span> <span class="keyword">operator</span> <span class="special">[](</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">TArraySubscriptCtx</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> + + <span class="comment">// Use the TArrayPrintCtx to display a TArray expression tree.</span> + <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span><span class="identifier">sout</span><span class="special">,</span> <span class="identifier">TArrayExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">TArrayPrintCtx</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Here is our TArray terminal, implemented in terms of TArrayExpr</span> +<span class="comment">// It is basically just an array of 3 integers.</span> +<span class="keyword">struct</span> <span class="identifier">TArray</span> + <span class="special">:</span> <span class="identifier">TArrayExpr</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="keyword">int</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">explicit</span> <span class="identifier">TArray</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">j</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">k</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">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">j</span><span class="special">;</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">k</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Here we override operator [] to give read/write access to</span> + <span class="comment">// the elements of the array. (We could use the TArrayExpr</span> + <span class="comment">// operator [] if we made the subscript context smarter about</span> + <span class="comment">// returning non-const reference when appropriate.)</span> + <span class="keyword">int</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">i</span><span class="special">];</span> + <span class="special">}</span> + + <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">[](</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">i</span><span class="special">];</span> + <span class="special">}</span> + + <span class="comment">// Here we define a operator = for TArray terminals that</span> + <span class="comment">// takes a TArray expression.</span> + <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> + <span class="identifier">TArray</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">=(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="comment">// proto::as_expr<TArrayDomain>(expr) is the same as</span> + <span class="comment">// expr unless expr is an integer, in which case it</span> + <span class="comment">// is made into a TArrayExpr terminal first.</span> + <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">TArrayDomain</span><span class="special">>(</span><span class="identifier">expr</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">Expr</span> <span class="special">></span> + <span class="identifier">TArray</span> <span class="special">&</span><span class="identifier">printAssign</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="special">*</span><span class="keyword">this</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">*</span><span class="keyword">this</span> <span class="special"><<</span> <span class="string">" = "</span> <span class="special"><<</span> <span class="identifier">expr</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> + <span class="special">}</span> + +<span class="keyword">private</span><span class="special">:</span> + <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> + <span class="identifier">TArray</span> <span class="special">&</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="comment">// expr[i] here uses TArraySubscriptCtx under the covers.</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">[</span><span class="number">0</span><span class="special">];</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">[</span><span class="number">1</span><span class="special">];</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">[</span><span class="number">2</span><span class="special">];</span> + <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">TArray</span> <span class="identifier">a</span><span class="special">(</span><span class="number">3</span><span class="special">,</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">);</span> + + <span class="identifier">TArray</span> <span class="identifier">b</span><span class="special">;</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="identifier">b</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="number">7</span><span class="special">;</span> <span class="identifier">b</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="number">33</span><span class="special">;</span> <span class="identifier">b</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="special">-</span><span class="number">99</span><span class="special">;</span> + + <span class="identifier">TArray</span> <span class="identifier">c</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">c</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="identifier">a</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">c</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">;</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="identifier">a</span><span class="special">.</span><span class="identifier">printAssign</span><span class="special">(</span><span class="identifier">b</span><span class="special">+</span><span class="identifier">c</span><span class="special">*(</span><span class="identifier">b</span> <span class="special">+</span> <span class="number">3</span><span class="special">*</span><span class="identifier">c</span><span class="special">));</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.vec3"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.vec3" title="Vec3: Computing With Transforms and Contexts">Vec3: Computing + With Transforms and Contexts</a> +</h4></div></div></div> +<p> + This is a simple example using <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><></span></code> to extend a terminal type with + additional behaviors, and using custom contexts and <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code> for evaluating expressions. It is a port + of the Vec3 example from <a href="http://www.codesourcery.com/pooma/download.html" target="_top">PETE</a>. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is a simple example using proto::extends to extend a terminal type with</span> +<span class="comment">// additional behaviors, and using custom contexts and proto::eval for</span> +<span class="comment">// evaluating expressions. It is a port of the Vec3 example</span> +<span class="comment">// from PETE (http://www.codesourcery.com/pooma/download.html).</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">functional</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">assert</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">mpl</span><span class="special">/</span><span class="keyword">int</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</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">proto</span><span class="special">/</span><span class="identifier">proto_typeof</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">proto</span><span class="special">/</span><span class="identifier">transform</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="comment">// Here is an evaluation context that indexes into a Vec3</span> +<span class="comment">// expression, and combines the result.</span> +<span class="keyword">struct</span> <span class="identifier">Vec3SubscriptCtx</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">Vec3SubscriptCtx</span> <span class="keyword">const</span> <span class="special">></span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">Vec3SubscriptCtx</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">i_</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Index array terminals with our subscript. Everything</span> + <span class="comment">// else will be handled by the default evaluation context.</span> + <span class="keyword">int</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">(&</span><span class="identifier">arr</span><span class="special">)[</span><span class="number">3</span><span class="special">])</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">[</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">i_</span><span class="special">];</span> + <span class="special">}</span> + + <span class="keyword">int</span> <span class="identifier">i_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// Here is an evaluation context that counts the number</span> +<span class="comment">// of Vec3 terminals in an expression.</span> +<span class="keyword">struct</span> <span class="identifier">CountLeavesCtx</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span> <span class="identifier">CountLeavesCtx</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">null_context</span> <span class="special">></span> +<span class="special">{</span> + <span class="identifier">CountLeavesCtx</span><span class="special">()</span> + <span class="special">:</span> <span class="identifier">count</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="keyword">void</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="keyword">int</span> <span class="keyword">const</span><span class="special">(&)[</span><span class="number">3</span><span class="special">])</span> + <span class="special">{</span> + <span class="special">++</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">count</span><span class="special">;</span> + <span class="special">}</span> + + <span class="keyword">int</span> <span class="identifier">count</span><span class="special">;</span> +<span class="special">};</span> + +<span class="keyword">struct</span> <span class="identifier">iplus</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="keyword">int</span><span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> <span class="special">{};</span> + +<span class="comment">// Here is a transform that does the same thing as the above context.</span> +<span class="comment">// It demonstrates the use of the std::plus<> function object</span> +<span class="comment">// with the fold transform. With minor modifications, this</span> +<span class="comment">// transform could be used to calculate the leaf count at compile</span> +<span class="comment">// time, rather than at runtime.</span> +<span class="keyword">struct</span> <span class="identifier">CountLeaves</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="comment">// match a Vec3 terminal, return 1</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">[</span><span class="number">3</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="number">1</span><span class="special">>()</span> <span class="special">></span> + <span class="comment">// match a terminal, return int() (which is 0)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">>,</span> <span class="keyword">int</span><span class="special">()</span> <span class="special">></span> + <span class="comment">// fold everything else, using std::plus<> to add</span> + <span class="comment">// the leaf count of each child to the accumulated state.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">otherwise</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="keyword">int</span><span class="special">(),</span> <span class="identifier">iplus</span><span class="special">(</span><span class="identifier">CountLeaves</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">)</span> <span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here is the Vec3 struct, which is a vector of 3 integers.</span> +<span class="keyword">struct</span> <span class="identifier">Vec3</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="keyword">int</span><span class="special">[</span><span class="number">3</span><span class="special">]>::</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">Vec3</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">explicit</span> <span class="identifier">Vec3</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">j</span><span class="special">=</span><span class="number">0</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">k</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">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">j</span><span class="special">;</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">k</span><span class="special">;</span> + <span class="special">}</span> + + <span class="keyword">int</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">[](</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">i</span><span class="special">];</span> + <span class="special">}</span> + + <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">[](</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">i</span><span class="special">];</span> + <span class="special">}</span> + + <span class="comment">// Here we define a operator = for Vec3 terminals that</span> + <span class="comment">// takes a Vec3 expression.</span> + <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">></span> + <span class="identifier">Vec3</span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">=(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">Vec3SubscriptCtx</span> <span class="keyword">const</span> <span class="identifier">CVec3SubscriptCtx</span><span class="special">;</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">CVec3SubscriptCtx</span><span class="special">(</span><span class="number">0</span><span class="special">));</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">CVec3SubscriptCtx</span><span class="special">(</span><span class="number">1</span><span class="special">));</span> + <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">CVec3SubscriptCtx</span><span class="special">(</span><span class="number">2</span><span class="special">));</span> + <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> + <span class="special">}</span> + + <span class="keyword">void</span> <span class="identifier">print</span><span class="special">()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> + <span class="special"><<</span> <span class="char">'}'</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// The count_leaves() function uses the CountLeaves transform and</span> +<span class="comment">// to count the number of leaves in an expression.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">int</span> <span class="identifier">count_leaves</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> +<span class="special">{</span> + <span class="comment">// Count the number of Vec3 terminals using the</span> + <span class="comment">// CountLeavesCtx evaluation context.</span> + <span class="identifier">CountLeavesCtx</span> <span class="identifier">ctx</span><span class="special">;</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + + <span class="comment">// This is another way to count the leaves using a transform.</span> + <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> + <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="identifier">CountLeaves</span><span class="special">()(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">count</span> <span class="special">);</span> + + <span class="keyword">return</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">count</span><span class="special">;</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">Vec3</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">;</span> + + <span class="identifier">c</span> <span class="special">=</span> <span class="number">4</span><span class="special">;</span> + + <span class="identifier">b</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> + <span class="identifier">b</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">=</span> <span class="special">-</span><span class="number">2</span><span class="special">;</span> + <span class="identifier">b</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="special">-</span><span class="number">3</span><span class="special">;</span> + + <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">;</span> + + <span class="identifier">a</span><span class="special">.</span><span class="identifier">print</span><span class="special">();</span> + + <span class="identifier">Vec3</span> <span class="identifier">d</span><span class="special">;</span> + <span class="identifier">BOOST_PROTO_AUTO</span><span class="special">(</span><span class="identifier">expr1</span><span class="special">,</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">);</span> + <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">expr1</span><span class="special">;</span> + <span class="identifier">d</span><span class="special">.</span><span class="identifier">print</span><span class="special">();</span> + + <span class="keyword">int</span> <span class="identifier">num</span> <span class="special">=</span> <span class="identifier">count_leaves</span><span class="special">(</span><span class="identifier">expr1</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">num</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="identifier">BOOST_PROTO_AUTO</span><span class="special">(</span><span class="identifier">expr2</span><span class="special">,</span> <span class="identifier">b</span> <span class="special">+</span> <span class="number">3</span> <span class="special">*</span> <span class="identifier">c</span><span class="special">);</span> + <span class="identifier">num</span> <span class="special">=</span> <span class="identifier">count_leaves</span><span class="special">(</span><span class="identifier">expr2</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">num</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="identifier">BOOST_PROTO_AUTO</span><span class="special">(</span><span class="identifier">expr3</span><span class="special">,</span> <span class="identifier">b</span> <span class="special">+</span> <span class="identifier">c</span> <span class="special">*</span> <span class="identifier">d</span><span class="special">);</span> + <span class="identifier">num</span> <span class="special">=</span> <span class="identifier">count_leaves</span><span class="special">(</span><span class="identifier">expr3</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">num</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.vector"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.vector" title="Vector: Adapting a Non-Proto Terminal Type">Vector: Adapting + a Non-Proto Terminal Type</a> +</h4></div></div></div> +<p> + This is an example of using <code class="computeroutput"><span class="identifier">BOOST_PROTO_DEFINE_OPERATORS</span><span class="special">()</span></code> to Protofy expressions using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><></span></code>, + a non-Proto type. It is a port of the Vector example from <a href="http://www.codesourcery.com/pooma/download.html" target="_top">PETE</a>. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is an example of using BOOST_PROTO_DEFINE_OPERATORS to Protofy</span> +<span class="comment">// expressions using std::vector<>, a non-proto type. It is a port of the</span> +<span class="comment">// Vector example from PETE (http://www.codesourcery.com/pooma/download.html).</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">stdexcept</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">mpl</span><span class="special">/</span><span class="keyword">bool</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">debug</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">proto</span><span class="special">/</span><span class="identifier">context</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">utility</span><span class="special">/</span><span class="identifier">enable_if</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">VectorExpr</span><span class="special">;</span> + +<span class="comment">// Here is an evaluation context that indexes into a std::vector</span> +<span class="comment">// expression and combines the result.</span> +<span class="keyword">struct</span> <span class="identifier">VectorSubscriptCtx</span> +<span class="special">{</span> + <span class="identifier">VectorSubscriptCtx</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">i_</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Unless this is a vector terminal, use the</span> + <span class="comment">// default evaluation context</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">EnableIf</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">VectorSubscriptCtx</span> <span class="keyword">const</span><span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// Index vector terminals with our subscript.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span> + <span class="identifier">Expr</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">_</span><span class="special">></span> <span class="special">></span> <span class="special">></span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value_type</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">VectorSubscriptCtx</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)[</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">i_</span><span class="special">];</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// Here is an evaluation context that verifies that all the</span> +<span class="comment">// vectors in an expression have the same size.</span> +<span class="keyword">struct</span> <span class="identifier">VectorSizeCtx</span> +<span class="special">{</span> + <span class="identifier">VectorSizeCtx</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">size_</span><span class="special">(</span><span class="identifier">size</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Unless this is a vector terminal, use the</span> + <span class="comment">// null evaluation context</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">EnableIf</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">null_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">VectorSizeCtx</span> <span class="keyword">const</span><span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// Index array terminals with our subscript. Everything</span> + <span class="comment">// else will be handled by the default evaluation context.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span> + <span class="identifier">Expr</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">_</span><span class="special">></span> <span class="special">></span> <span class="special">></span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">VectorSizeCtx</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">if</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">.</span><span class="identifier">size_</span> <span class="special">!=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">expr</span><span class="special">).</span><span class="identifier">size</span><span class="special">())</span> + <span class="special">{</span> + <span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span><span class="string">"LHS and RHS are not compatible"</span><span class="special">);</span> + <span class="special">}</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// A grammar which matches all the assignment operators,</span> +<span class="comment">// so we can easily disable them.</span> +<span class="keyword">struct</span> <span class="identifier">AssignOps</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">switch_</span><span class="special"><</span><span class="keyword">struct</span> <span class="identifier">AssignOpsCases</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here are the cases used by the switch_ above.</span> +<span class="keyword">struct</span> <span class="identifier">AssignOpsCases</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">D</span> <span class="special">=</span> <span class="number">0</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">{};</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">minus_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">multiplies_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">divides_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">modulus_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_left_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_right_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_and_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_or_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_xor_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> +<span class="special">};</span> + +<span class="comment">// A vector grammar is a terminal or some op that is not an</span> +<span class="comment">// assignment op. (Assignment will be handled specially.)</span> +<span class="keyword">struct</span> <span class="identifier">VectorGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">and_</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">VectorGrammar</span><span class="special">></span> <span class="special">>,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">AssignOps</span><span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Expressions in the vector domain will be wrapped in VectorExpr<></span> +<span class="comment">// and must conform to the VectorGrammar</span> +<span class="keyword">struct</span> <span class="identifier">VectorDomain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">VectorExpr</span><span class="special">>,</span> <span class="identifier">VectorGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here is VectorExpr, which extends a proto expr type by</span> +<span class="comment">// giving it an operator [] which uses the VectorSubscriptCtx</span> +<span class="comment">// to evaluate an expression with a given index.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">VectorExpr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">VectorExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">VectorDomain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">explicit</span> <span class="identifier">VectorExpr</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">VectorExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">VectorDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="comment">// Use the VectorSubscriptCtx to implement subscripting</span> + <span class="comment">// of a Vector expression tree.</span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">Expr</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">VectorSubscriptCtx</span> <span class="keyword">const</span><span class="special">>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">[](</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">VectorSubscriptCtx</span> <span class="keyword">const</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Define a trait type for detecting vector terminals, to</span> +<span class="comment">// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.</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">IsVector</span> + <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">false_</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">typename</span> <span class="identifier">A</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">IsVector</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">></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="keyword">namespace</span> <span class="identifier">VectorOps</span> +<span class="special">{</span> + <span class="comment">// This defines all the overloads to make expressions involving</span> + <span class="comment">// std::vector to build expression templates.</span> + <span class="identifier">BOOST_PROTO_DEFINE_OPERATORS</span><span class="special">(</span><span class="identifier">IsVector</span><span class="special">,</span> <span class="identifier">VectorDomain</span><span class="special">)</span> + + <span class="keyword">typedef</span> <span class="identifier">VectorSubscriptCtx</span> <span class="keyword">const</span> <span class="identifier">CVectorSubscriptCtx</span><span class="special">;</span> + + <span class="comment">// Assign to a vector from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">VectorSizeCtx</span> <span class="keyword">const</span> <span class="identifier">size</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">VectorDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">size</span><span class="special">);</span> <span class="comment">// will throw if the sizes don't match</span> + <span class="keyword">for</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">arr</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">VectorDomain</span><span class="special">>(</span><span class="identifier">expr</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">arr</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Add-assign to a vector from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">+=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">VectorSizeCtx</span> <span class="keyword">const</span> <span class="identifier">size</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">VectorDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">size</span><span class="special">);</span> <span class="comment">// will throw if the sizes don't match</span> + <span class="keyword">for</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">arr</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">+=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">VectorDomain</span><span class="special">>(</span><span class="identifier">expr</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">arr</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">VectorOps</span><span class="special">;</span> + + <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> + <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">e</span><span class="special">(</span><span class="identifier">n</span><span class="special">);</span> + + <span class="keyword">for</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">a</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">b</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">2</span><span class="special">*</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">c</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">3</span><span class="special">*</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">d</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> + <span class="special">}</span> + + <span class="identifier">VectorOps</span><span class="special">::</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span> + <span class="identifier">VectorOps</span><span class="special">::</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">*</span> <span class="identifier">c</span><span class="special">);</span> + <span class="identifier">a</span> <span class="special">+=</span> <span class="identifier">if_else</span><span class="special">(</span><span class="identifier">d</span> <span class="special"><</span> <span class="number">30</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">);</span> + + <span class="identifier">VectorOps</span><span class="special">::</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">e</span><span class="special">,</span> <span class="identifier">c</span><span class="special">);</span> + <span class="identifier">e</span> <span class="special">+=</span> <span class="identifier">e</span> <span class="special">-</span> <span class="number">4</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">c</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span> + + <span class="keyword">for</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> + <span class="special"><<</span> <span class="string">" a("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" b("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">b</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" c("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">c</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" d("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">d</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" e("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.mixed"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.mixed" title="Mixed: Adapting Several Non-Proto Terminal Types">Mixed: Adapting + Several Non-Proto Terminal Types</a> +</h4></div></div></div> +<p> + This is an example of using <code class="computeroutput"><span class="identifier">BOOST_PROTO_DEFINE_OPERATORS</span><span class="special">()</span></code> to Protofy expressions using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><></span></code> + and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><></span></code>, + non-Proto types. It is a port of the Mixed example from <a href="http://www.codesourcery.com/pooma/download.html" target="_top">PETE</a>. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is an example of using BOOST_PROTO_DEFINE_OPERATORS to Protofy</span> +<span class="comment">// expressions using std::vector<> and std::list, non-proto types. It is a port</span> +<span class="comment">// of the Mixed example from PETE.</span> +<span class="comment">// (http://www.codesourcery.com/pooma/download.html).</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">list</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cmath</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">complex</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">stdexcept</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">debug</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">proto</span><span class="special">/</span><span class="identifier">context</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">proto</span><span class="special">/</span><span class="identifier">transform</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">utility</span><span class="special">/</span><span class="identifier">enable_if</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">list</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">vector</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">complex</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">type_traits</span><span class="special">/</span><span class="identifier">remove_reference</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">MixedExpr</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">iterator_wrapper</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">Iter</span> <span class="identifier">iterator</span><span class="special">;</span> + + <span class="keyword">explicit</span> <span class="identifier">iterator_wrapper</span><span class="special">(</span><span class="identifier">Iter</span> <span class="identifier">iter</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">it</span><span class="special">(</span><span class="identifier">iter</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="keyword">mutable</span> <span class="identifier">Iter</span> <span class="identifier">it</span><span class="special">;</span> +<span class="special">};</span> + +<span class="keyword">struct</span> <span class="identifier">begin</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Sig</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">This</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Cont</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">Cont</span><span class="special">)></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span> + <span class="identifier">iterator_wrapper</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">Cont</span><span class="special">>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">const_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">Cont</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">Cont</span> <span class="keyword">const</span> <span class="special">&)>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Cont</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">cont</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">iterator_wrapper</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Cont</span><span class="special">::</span><span class="identifier">const_iterator</span><span class="special">></span> <span class="identifier">it</span><span class="special">(</span><span class="identifier">cont</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">it</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Here is a grammar that replaces vector and list terminals with their</span> +<span class="comment">// begin iterators</span> +<span class="keyword">struct</span> <span class="identifier">Begin</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">_</span><span class="special">></span> <span class="special">>,</span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">_</span><span class="special">></span> <span class="special">>,</span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">Begin</span><span class="special">></span> <span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here is an evaluation context that dereferences iterator</span> +<span class="comment">// terminals.</span> +<span class="keyword">struct</span> <span class="identifier">DereferenceCtx</span> +<span class="special">{</span> + <span class="comment">// Unless this is an iterator terminal, use the</span> + <span class="comment">// default evaluation context</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">EnableIf</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">DereferenceCtx</span> <span class="keyword">const</span><span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// Dereference iterator terminals.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span> + <span class="identifier">Expr</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">iterator_wrapper</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> <span class="special">></span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">IteratorWrapper</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">IteratorWrapper</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">iterator</span><span class="special">;</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">iterator</span><span class="special">>::</span><span class="identifier">reference</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">DereferenceCtx</span> <span class="keyword">const</span> <span class="special">&)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="special">*</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">expr</span><span class="special">).</span><span class="identifier">it</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> +<span class="special">};</span> + +<span class="comment">// Here is an evaluation context that increments iterator</span> +<span class="comment">// terminals.</span> +<span class="keyword">struct</span> <span class="identifier">IncrementCtx</span> +<span class="special">{</span> + <span class="comment">// Unless this is an iterator terminal, use the</span> + <span class="comment">// default evaluation context</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">EnableIf</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">null_eval</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">IncrementCtx</span> <span class="keyword">const</span><span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// advance iterator terminals.</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">eval</span><span class="special"><</span> + <span class="identifier">Expr</span> + <span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">iterator_wrapper</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> <span class="special">></span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="special">></span> + <span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> + + <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Expr</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">IncrementCtx</span> <span class="keyword">const</span> <span class="special">&)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="special">++</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">expr</span><span class="special">).</span><span class="identifier">it</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> +<span class="special">};</span> + +<span class="comment">// A grammar which matches all the assignment operators,</span> +<span class="comment">// so we can easily disable them.</span> +<span class="keyword">struct</span> <span class="identifier">AssignOps</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">switch_</span><span class="special"><</span><span class="keyword">struct</span> <span class="identifier">AssignOpsCases</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here are the cases used by the switch_ above.</span> +<span class="keyword">struct</span> <span class="identifier">AssignOpsCases</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tag</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">D</span> <span class="special">=</span> <span class="number">0</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">{};</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">minus_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">multiplies_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">divides_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">modulus_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_left_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">shift_right_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_and_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_or_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">int</span> <span class="identifier">D</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">case_</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">bitwise_xor_assign</span><span class="special">,</span> <span class="identifier">D</span> <span class="special">></span> <span class="special">:</span> <span class="identifier">_</span> <span class="special">{};</span> +<span class="special">};</span> + +<span class="comment">// An expression conforms to the MixedGrammar if it is a terminal or some</span> +<span class="comment">// op that is not an assignment op. (Assignment will be handled specially.)</span> +<span class="keyword">struct</span> <span class="identifier">MixedGrammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">and_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">MixedGrammar</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">not_</span><span class="special"><</span><span class="identifier">AssignOps</span><span class="special">></span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Expressions in the MixedDomain will be wrapped in MixedExpr<></span> +<span class="comment">// and must conform to the MixedGrammar</span> +<span class="keyword">struct</span> <span class="identifier">MixedDomain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">MixedExpr</span><span class="special">>,</span> <span class="identifier">MixedGrammar</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Here is MixedExpr, a wrapper for expression types in the MixedDomain.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">MixedExpr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">MixedExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">MixedDomain</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">explicit</span> <span class="identifier">MixedExpr</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">MixedExpr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{}</span> +<span class="keyword">private</span><span class="special">:</span> + <span class="comment">// hide this:</span> + <span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">MixedExpr</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">>,</span> <span class="identifier">MixedDomain</span><span class="special">>::</span><span class="keyword">operator</span> <span class="special">[];</span> +<span class="special">};</span> + +<span class="comment">// Define a trait type for detecting vector and list terminals, to</span> +<span class="comment">// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.</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">IsMixed</span> + <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">false_</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">typename</span> <span class="identifier">A</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">IsMixed</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">></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="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">IsMixed</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">></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="keyword">namespace</span> <span class="identifier">MixedOps</span> +<span class="special">{</span> + <span class="comment">// This defines all the overloads to make expressions involving</span> + <span class="comment">// std::vector to build expression templates.</span> + <span class="identifier">BOOST_PROTO_DEFINE_OPERATORS</span><span class="special">(</span><span class="identifier">IsMixed</span><span class="special">,</span> <span class="identifier">MixedDomain</span><span class="special">)</span> + + <span class="keyword">struct</span> <span class="identifier">assign_op</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">typename</span> <span class="identifier">U</span><span class="special">></span> + <span class="keyword">void</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">T</span> <span class="special">&</span><span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">u</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">t</span> <span class="special">=</span> <span class="identifier">u</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="keyword">struct</span> <span class="identifier">plus_assign_op</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">typename</span> <span class="identifier">U</span><span class="special">></span> + <span class="keyword">void</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">T</span> <span class="special">&</span><span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">u</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">t</span> <span class="special">+=</span> <span class="identifier">u</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="keyword">struct</span> <span class="identifier">minus_assign_op</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">typename</span> <span class="identifier">U</span><span class="special">></span> + <span class="keyword">void</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">T</span> <span class="special">&</span><span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">u</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">t</span> <span class="special">-=</span> <span class="identifier">u</span><span class="special">;</span> + <span class="special">}</span> + <span class="special">};</span> + + <span class="keyword">struct</span> <span class="identifier">sin_</span> + <span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Sig</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">This</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Arg</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">Arg</span><span class="special">)></span> + <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_const</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">Arg</span><span class="special">>::</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">Arg</span><span class="special">></span> + <span class="identifier">Arg</span> <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">Arg</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">sin</span><span class="special">(</span><span class="identifier">a</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">A</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span> + <span class="special">,</span> <span class="identifier">MixedDomain</span> + <span class="special">,</span> <span class="identifier">sin_</span> <span class="keyword">const</span> + <span class="special">,</span> <span class="identifier">A</span> <span class="keyword">const</span> <span class="special">&</span> + <span class="special">>::</span><span class="identifier">type</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">A</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">)</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span><span class="special">,</span> <span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">sin_</span><span class="special">(),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span><span class="identifier">a</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">FwdIter</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Op</span><span class="special">></span> + <span class="keyword">void</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">FwdIter</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">FwdIter</span> <span class="identifier">end</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Op</span> <span class="identifier">op</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">IncrementCtx</span> <span class="keyword">const</span> <span class="identifier">inc</span> <span class="special">=</span> <span class="special">{};</span> + <span class="identifier">DereferenceCtx</span> <span class="keyword">const</span> <span class="identifier">deref</span> <span class="special">=</span> <span class="special">{};</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">Begin</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&)>::</span><span class="identifier">type</span> <span class="identifier">expr2</span> <span class="special">=</span> <span class="identifier">Begin</span><span class="special">()(</span><span class="identifier">expr</span><span class="special">);</span> + <span class="keyword">for</span><span class="special">(;</span> <span class="identifier">begin</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">;</span> <span class="special">++</span><span class="identifier">begin</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">op</span><span class="special">(*</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr2</span><span class="special">,</span> <span class="identifier">deref</span><span class="special">));</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr2</span><span class="special">,</span> <span class="identifier">inc</span><span class="special">);</span> + <span class="special">}</span> + <span class="special">}</span> + + <span class="comment">// Add-assign to a vector from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">assign_op</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Add-assign to a list from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">assign_op</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Add-assign to a vector from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">+=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">plus_assign_op</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Add-assign to a list from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">+=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">plus_assign_op</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Minus-assign to a vector from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">-=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">minus_assign_op</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">;</span> + <span class="special">}</span> + + <span class="comment">// Minus-assign to a list from some expression.</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">typename</span> <span class="identifier">A</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="keyword">operator</span> <span class="special">-=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span><span class="identifier">arr</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">expr</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">arr</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">arr</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special"><</span><span class="identifier">MixedDomain</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">minus_assign_op</span><span class="special">());</span> + <span class="keyword">return</span> <span class="identifier">arr</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">MixedOps</span><span class="special">;</span> + + <span class="keyword">int</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">e</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="special">></span> <span class="identifier">f</span><span class="special">;</span> + + <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> + <span class="keyword">for</span><span class="special">(</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span><span class="identifier">i</span> <span class="special"><</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">a</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">b</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">2</span><span class="special">*</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">c</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">3</span><span class="special">*</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">d</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> + <span class="identifier">e</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">0.0</span><span class="special">);</span> + <span class="identifier">f</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> + <span class="special">}</span> + + <span class="identifier">MixedOps</span><span class="special">::</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span> + <span class="identifier">MixedOps</span><span class="special">::</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span> <span class="special">*</span> <span class="identifier">c</span><span class="special">);</span> + <span class="identifier">a</span> <span class="special">+=</span> <span class="identifier">if_else</span><span class="special">(</span><span class="identifier">d</span> <span class="special"><</span> <span class="number">30</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">);</span> + + <span class="identifier">MixedOps</span><span class="special">::</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">e</span><span class="special">,</span> <span class="identifier">c</span><span class="special">);</span> + <span class="identifier">e</span> <span class="special">+=</span> <span class="identifier">e</span> <span class="special">-</span> <span class="number">4</span> <span class="special">/</span> <span class="special">(</span><span class="identifier">c</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span> + + <span class="identifier">f</span> <span class="special">-=</span> <span class="identifier">sin</span><span class="special">(</span><span class="number">0.1</span> <span class="special">*</span> <span class="identifier">e</span> <span class="special">*</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">0.2</span><span class="special">,</span> <span class="number">1.2</span><span class="special">));</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">const_iterator</span> <span class="identifier">ei</span> <span class="special">=</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="special">>::</span><span class="identifier">const_iterator</span> <span class="identifier">fi</span> <span class="special">=</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> + <span class="keyword">for</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> + <span class="special"><<</span> <span class="string">"a("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" b("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">b</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" c("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">c</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" d("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">d</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> + <span class="special"><<</span> <span class="string">" e("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">ei</span><span class="special">++</span> + <span class="special"><<</span> <span class="string">" f("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">fi</span><span class="special">++</span> + <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.map_assign"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.map_assign" title="Map Assign: An Intermediate Transform">Map Assign: + An Intermediate Transform</a> +</h4></div></div></div> +<p> + A demonstration of how to implement <code class="computeroutput"><span class="identifier">map_list_of</span><span class="special">()</span></code> from the Boost.Assign library using Proto. + <code class="computeroutput"><span class="identifier">map_list_assign</span><span class="special">()</span></code> + is used to conveniently initialize a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><></span></code>. By using Proto, we can avoid any + dynamic allocation while building the intermediate representation. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is a port of map_list_of() from the Boost.Assign library.</span> +<span class="comment">// It has the advantage of being more efficient at runtime by not</span> +<span class="comment">// building any temporary container that requires dynamic allocation.</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">map</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">transform</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">type_traits</span><span class="special">/</span><span class="identifier">add_reference</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">map_list_of_tag</span> +<span class="special">{};</span> + +<span class="comment">// A simple callable function object that inserts a</span> +<span class="comment">// (key,value) pair into a map.</span> +<span class="keyword">struct</span> <span class="identifier">insert</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Sig</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">This</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Map</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Key</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">Map</span><span class="special">,</span> <span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">)></span> + <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_reference</span><span class="special"><</span><span class="identifier">Map</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">Map</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Key</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">></span> + <span class="identifier">Map</span> <span class="special">&</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Map</span> <span class="special">&</span><span class="identifier">map</span><span class="special">,</span> <span class="identifier">Key</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">key</span><span class="special">,</span> <span class="identifier">Value</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">value</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">map</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">Map</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">(</span><span class="identifier">key</span><span class="special">,</span> <span class="identifier">value</span><span class="special">));</span> + <span class="keyword">return</span> <span class="identifier">map</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Work-arounds for Microsoft Visual C++ 7.1</span> +<span class="preprocessor">#if</span> <span class="identifier">BOOST_WORKAROUND</span><span class="special">(</span><span class="identifier">BOOST_MSVC</span><span class="special">,</span> <span class="special">==</span> <span class="number">1310</span><span class="special">)</span> +<span class="preprocessor">#define</span> <span class="identifier">MapListOf</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><span class="identifier">MapListOf</span><span class="special">(</span><span class="identifier">x</span><span class="special">)></span> +<span class="preprocessor">#define</span> <span class="identifier">_value</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">call</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">(</span><span class="identifier">x</span><span class="special">)></span> +<span class="preprocessor">#endif</span> + +<span class="comment">// The grammar for valid map-list expressions, and a</span> +<span class="comment">// transform that populates the map.</span> +<span class="keyword">struct</span> <span class="identifier">MapListOf</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="comment">// map_list_of(a,b)</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">map_list_of_tag</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">insert</span><span class="special">(</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_data</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child1</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child2</span><span class="special">)</span> + <span class="special">)</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="comment">// map_list_of(a,b)(c,d)...</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> + <span class="identifier">MapListOf</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">insert</span><span class="special">(</span> + <span class="identifier">MapListOf</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child0</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child1</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_child2</span><span class="special">)</span> + <span class="special">)</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="preprocessor">#if</span> <span class="identifier">BOOST_WORKAROUND</span><span class="special">(</span><span class="identifier">BOOST_MSVC</span><span class="special">,</span> <span class="special">==</span> <span class="number">1310</span><span class="special">)</span> +<span class="preprocessor">#undef</span> <span class="identifier">MapListOf</span> +<span class="preprocessor">#undef</span> <span class="identifier">_value</span> +<span class="preprocessor">#endif</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">map_list_of_expr</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">map_list_of_dom</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pod_generator</span><span class="special"><</span><span class="identifier">map_list_of_expr</span><span class="special">>,</span> <span class="identifier">MapListOf</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// An expression wrapper that provides a conversion to a</span> +<span class="comment">// map that uses the MapListOf</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">map_list_of_expr</span> +<span class="special">{</span> + <span class="identifier">BOOST_PROTO_BASIC_EXTENDS</span><span class="special">(</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">map_list_of_expr</span><span class="special">,</span> <span class="identifier">map_list_of_dom</span><span class="special">)</span> + <span class="identifier">BOOST_PROTO_EXTENDS_FUNCTION</span><span class="special">()</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Key</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Cmp</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Al</span><span class="special">></span> + <span class="keyword">operator</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Cmp</span><span class="special">,</span> <span class="identifier">Al</span><span class="special">></span> <span class="special">()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">MapListOf</span><span class="special">>));</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Cmp</span><span class="special">,</span> <span class="identifier">Al</span><span class="special">></span> <span class="identifier">map</span><span class="special">;</span> + <span class="keyword">return</span> <span class="identifier">MapListOf</span><span class="special">()(*</span><span class="keyword">this</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">map</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="identifier">map_list_of_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">map_list_of_tag</span><span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">map_list_of</span> <span class="special">=</span> <span class="special">{{{}}};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Initialize a map:</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</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="keyword">int</span><span class="special">></span> <span class="identifier">op</span> <span class="special">=</span> + <span class="identifier">map_list_of</span> + <span class="special">(</span><span class="string">"<"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> + <span class="special">(</span><span class="string">"<="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> + <span class="special">(</span><span class="string">">"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span> + <span class="special">(</span><span class="string">">="</span><span class="special">,</span><span class="number">4</span><span class="special">)</span> + <span class="special">(</span><span class="string">"="</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span> + <span class="special">(</span><span class="string">"<>"</span><span class="special">,</span><span class="number">6</span><span class="special">)</span> + <span class="special">;</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"<\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"<"</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"<=\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"<="</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\">\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">">"</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\">=\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">">="</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"=\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"="</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"<>\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"<>"</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.future_group"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.future_group" title="Future Group: A More Advanced Transform">Future + Group: A More Advanced Transform</a> +</h4></div></div></div> +<p> + An advanced example of a Proto transform that implements Howard Hinnant's + design for <span class="emphasis"><em>future groups</em></span> that block for all or some + asynchronous operations to complete and returns their results in a tuple + of the appropriate type. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is an example of using Proto transforms to implement</span> +<span class="comment">// Howard Hinnant's future group proposal.</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">vector</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">as_vector</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">joint_view</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">single_view</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">transform</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">fusion</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="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">L</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">R</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">pick_left</span> +<span class="special">{</span> + <span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">R</span><span class="special">>));</span> + <span class="keyword">typedef</span> <span class="identifier">L</span> <span class="identifier">type</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// Work-arounds for Microsoft Visual C++ 7.1</span> +<span class="preprocessor">#if</span> <span class="identifier">BOOST_WORKAROUND</span><span class="special">(</span><span class="identifier">BOOST_MSVC</span><span class="special">,</span> <span class="special">==</span> <span class="number">1310</span><span class="special">)</span> +<span class="preprocessor">#define</span> <span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">call</span><span class="special"><</span><span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">x</span><span class="special">)></span> +<span class="preprocessor">#endif</span> + +<span class="comment">// Define the grammar of future group expression, as well as a</span> +<span class="comment">// transform to turn them into a Fusion sequence of the correct</span> +<span class="comment">// type.</span> +<span class="keyword">struct</span> <span class="identifier">FutureGroup</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="comment">// terminals become a single-element Fusion sequence</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">single_view</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">>(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> + <span class="comment">// (a && b) becomes a concatenation of the sequence</span> + <span class="comment">// from 'a' and the one from 'b':</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_and</span><span class="special"><</span><span class="identifier">FutureGroup</span><span class="special">,</span> <span class="identifier">FutureGroup</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">joint_view</span><span class="special"><</span> + <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_const</span><span class="special"><</span><span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">)</span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_const</span><span class="special"><</span><span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">)</span> <span class="special">></span> + <span class="special">>(</span><span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">),</span> <span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">))</span> + <span class="special">></span> + <span class="comment">// (a || b) becomes the sequence for 'a', so long</span> + <span class="comment">// as it is the same as the sequence for 'b'.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">logical_or</span><span class="special"><</span><span class="identifier">FutureGroup</span><span class="special">,</span> <span class="identifier">FutureGroup</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">pick_left</span><span class="special"><</span> + <span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">)</span> + <span class="special">,</span> <span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">)</span> + <span class="special">>(</span><span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">))</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="preprocessor">#if</span> <span class="identifier">BOOST_WORKAROUND</span><span class="special">(</span><span class="identifier">BOOST_MSVC</span><span class="special">,</span> <span class="special">==</span> <span class="number">1310</span><span class="special">)</span> +<span class="preprocessor">#undef</span> <span class="identifier">FutureGroup</span> +<span class="preprocessor">#endif</span> + +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">E</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">future_expr</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">future_dom</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">future_expr</span><span class="special">>,</span> <span class="identifier">FutureGroup</span><span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// Expressions in the future group domain have a .get()</span> +<span class="comment">// member function that (ostensibly) blocks for the futures</span> +<span class="comment">// to complete and returns the results in an appropriate</span> +<span class="comment">// tuple.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">E</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">future_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">E</span><span class="special">,</span> <span class="identifier">future_expr</span><span class="special"><</span><span class="identifier">E</span><span class="special">>,</span> <span class="identifier">future_dom</span><span class="special">></span> +<span class="special">{</span> + <span class="keyword">explicit</span> <span class="identifier">future_expr</span><span class="special">(</span><span class="identifier">E</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">e</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">future_expr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span> + <span class="special">{}</span> + + <span class="keyword">typename</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">as_vector</span><span class="special"><</span> + <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">FutureGroup</span><span class="special">(</span><span class="identifier">E</span><span class="special">)>::</span><span class="identifier">type</span> + <span class="special">>::</span><span class="identifier">type</span> + <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">as_vector</span><span class="special">(</span><span class="identifier">FutureGroup</span><span class="special">()(*</span><span class="keyword">this</span><span class="special">));</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// The future<> type has an even simpler .get()</span> +<span class="comment">// member function.</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">future</span> + <span class="special">:</span> <span class="identifier">future_expr</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">future</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">t</span> <span class="special">=</span> <span class="identifier">T</span><span class="special">())</span> + <span class="special">:</span> <span class="identifier">future</span><span class="special">::</span><span class="identifier">proto_derived_expr</span><span class="special">(</span><span class="identifier">future</span><span class="special">::</span><span class="identifier">proto_base_expr</span><span class="special">::</span><span class="identifier">make</span><span class="special">(</span><span class="identifier">t</span><span class="special">))</span> + <span class="special">{}</span> + + <span class="identifier">T</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// TEST CASES</span> +<span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{};</span> +<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{};</span> +<span class="keyword">struct</span> <span class="identifier">C</span> <span class="special">{};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="keyword">using</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">vector</span><span class="special">;</span> + <span class="identifier">future</span><span class="special"><</span><span class="identifier">A</span><span class="special">></span> <span class="identifier">a</span><span class="special">;</span> + <span class="identifier">future</span><span class="special"><</span><span class="identifier">B</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span> + <span class="identifier">future</span><span class="special"><</span><span class="identifier">C</span><span class="special">></span> <span class="identifier">c</span><span class="special">;</span> + <span class="identifier">future</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">B</span><span class="special">></span> <span class="special">></span> <span class="identifier">ab</span><span class="special">;</span> + + <span class="comment">// Verify that various future groups have the</span> + <span class="comment">// correct return types.</span> + <span class="identifier">A</span> <span class="identifier">t0</span> <span class="special">=</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span> + <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t1</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">&&</span> <span class="identifier">b</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> + <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t2</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">a</span> <span class="special">||</span> <span class="identifier">a</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> + <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t3</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">a</span> <span class="special">&&</span> <span class="identifier">b</span> <span class="special">||</span> <span class="identifier">a</span> <span class="special">&&</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> + <span class="identifier">vector</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">>,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t4</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">ab</span> <span class="special">||</span> <span class="identifier">ab</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> + + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.lambda"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.lambda" title="Lambda: A Simple Lambda Library with Proto">Lambda: A + Simple Lambda Library with Proto</a> +</h4></div></div></div> +<p> + This is an advanced example that shows how to implement a simple lambda + EDSL with Proto, like the Boost.Lambda_library. It uses contexts, transforms + and expression extension. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">///////////////////////////////////////////////////////////////////////////////</span> +<span class="comment">// Copyright 2008 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This example builds a simple but functional lambda library using Proto.</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</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">mpl</span><span class="special">/</span><span class="keyword">int</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">mpl</span><span class="special">/</span><span class="identifier">min_max</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">mpl</span><span class="special">/</span><span class="identifier">eval_if</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">mpl</span><span class="special">/</span><span class="identifier">identity</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">mpl</span><span class="special">/</span><span class="identifier">next_prior</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">tuple</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">typeof</span><span class="special">/</span><span class="identifier">typeof</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">ostream</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">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">iostream</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">proto</span><span class="special">/</span><span class="identifier">core</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">proto</span><span class="special">/</span><span class="identifier">context</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">proto</span><span class="special">/</span><span class="identifier">transform</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">fusion</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="keyword">using</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">;</span> + +<span class="comment">// Forward declaration of the lambda expression wrapper</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">lambda</span><span class="special">;</span> + +<span class="keyword">struct</span> <span class="identifier">lambda_domain</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">pod_generator</span><span class="special"><</span><span class="identifier">lambda</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">I</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">placeholder</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">I</span> <span class="identifier">arity</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">placeholder_arity</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">::</span><span class="identifier">arity</span> <span class="identifier">type</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// The lambda grammar, with the transforms for calculating the max arity</span> +<span class="keyword">struct</span> <span class="identifier">lambda_arity</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">next</span><span class="special"><</span><span class="identifier">placeholder_arity</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">></span> <span class="special">>()</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">_</span><span class="special">></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="number">0</span><span class="special">>()</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">nary_expr</span><span class="special"><</span><span class="identifier">_</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">vararg</span><span class="special"><</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">fold</span><span class="special"><</span><span class="identifier">_</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="number">0</span><span class="special">>(),</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">max</span><span class="special"><</span><span class="identifier">lambda_arity</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">>()></span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="comment">// The lambda context is the same as the default context</span> +<span class="comment">// with the addition of special handling for lambda placeholders</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">lambda_context</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special"><</span><span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">Tuple</span><span class="special">></span> <span class="keyword">const</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">lambda_context</span><span class="special">(</span><span class="identifier">Tuple</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">args</span><span class="special">)</span> + <span class="special">:</span> <span class="identifier">args_</span><span class="special">(</span><span class="identifier">args</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">Sig</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">This</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&)></span> + <span class="special">:</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">at</span><span class="special"><</span><span class="identifier">Tuple</span><span class="special">,</span> <span class="identifier">I</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">I</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">at</span><span class="special"><</span><span class="identifier">Tuple</span><span class="special">,</span> <span class="identifier">I</span><span class="special">>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">return</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">at</span><span class="special"><</span><span class="identifier">I</span><span class="special">>(</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">args_</span><span class="special">);</span> + <span class="special">}</span> + + <span class="identifier">Tuple</span> <span class="identifier">args_</span><span class="special">;</span> +<span class="special">};</span> + +<span class="comment">// The lambda<> expression wrapper makes expressions polymorphic</span> +<span class="comment">// function objects</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">lambda</span> +<span class="special">{</span> + <span class="identifier">BOOST_PROTO_BASIC_EXTENDS</span><span class="special">(</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">lambda</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">lambda_domain</span><span class="special">)</span> + <span class="identifier">BOOST_PROTO_EXTENDS_ASSIGN</span><span class="special">()</span> + <span class="identifier">BOOST_PROTO_EXTENDS_SUBSCRIPT</span><span class="special">()</span> + + <span class="comment">// Calculate the arity of this lambda expression</span> + <span class="keyword">static</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">arity</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span><span class="special"><</span><span class="identifier">lambda_arity</span><span class="special">(</span><span class="identifier">T</span><span class="special">)>::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">value</span><span class="special">;</span> + + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Sig</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special">;</span> + + <span class="comment">// Define nested result<> specializations to calculate the return</span> + <span class="comment">// type of this lambda expression. But be careful not to evaluate</span> + <span class="comment">// the return type of the nullary function unless we have a nullary</span> + <span class="comment">// lambda!</span> + <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">This</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">()></span> + <span class="special">:</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">eval_if_c</span><span class="special"><</span> + <span class="number">0</span> <span class="special">==</span> <span class="identifier">arity</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><></span> <span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">identity</span><span class="special"><</span><span class="keyword">void</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">This</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A0</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">A0</span><span class="special">)></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A0</span><span class="special">></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">This</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A1</span><span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">This</span><span class="special">(</span><span class="identifier">A0</span><span class="special">,</span> <span class="identifier">A1</span><span class="special">)></span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">eval</span><span class="special"><</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">,</span> <span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A0</span><span class="special">,</span> <span class="identifier">A1</span><span class="special">></span> <span class="special">></span> <span class="special">></span> + <span class="special">{};</span> + + <span class="comment">// Define our operator () that evaluates the lambda expression.</span> + <span class="keyword">typename</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">lambda</span><span class="special">()>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()()</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><></span> <span class="identifier">args</span><span class="special">;</span> + <span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><></span> <span class="special">></span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">args</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</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">A0</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">lambda</span><span class="special">(</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&)>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a0</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&></span> <span class="identifier">args</span><span class="special">(</span><span class="identifier">a0</span><span class="special">);</span> + <span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&></span> <span class="special">></span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">args</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</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">A0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A1</span><span class="special">></span> + <span class="keyword">typename</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">lambda</span><span class="special">(</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&)>::</span><span class="identifier">type</span> + <span class="keyword">operator</span> <span class="special">()(</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a1</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&></span> <span class="identifier">args</span><span class="special">(</span><span class="identifier">a0</span><span class="special">,</span> <span class="identifier">a1</span><span class="special">);</span> + <span class="identifier">lambda_context</span><span class="special"><</span><span class="identifier">fusion</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">A0</span> <span class="keyword">const</span> <span class="special">&,</span> <span class="identifier">A1</span> <span class="keyword">const</span> <span class="special">&></span> <span class="special">></span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">args</span><span class="special">);</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Define some lambda placeholders</span> +<span class="identifier">lambda</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</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="number">0</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> +<span class="identifier">lambda</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</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="number">1</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">_2</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="identifier">lambda</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">val</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">t</span><span class="special">)</span> +<span class="special">{</span> + <span class="identifier">lambda</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="identifier">that</span> <span class="special">=</span> <span class="special">{{</span><span class="identifier">t</span><span class="special">}};</span> + <span class="keyword">return</span> <span class="identifier">that</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="identifier">lambda</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">T</span> <span class="special">&>::</span><span class="identifier">type</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">var</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span><span class="identifier">t</span><span class="special">)</span> +<span class="special">{</span> + <span class="identifier">lambda</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">T</span> <span class="special">&>::</span><span class="identifier">type</span><span class="special">></span> <span class="identifier">that</span> <span class="special">=</span> <span class="special">{{</span><span class="identifier">t</span><span class="special">}};</span> + <span class="keyword">return</span> <span class="identifier">that</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">construct_helper</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">result_type</span><span class="special">;</span> <span class="comment">// for TR1 result_of</span> + + <span class="identifier">T</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="keyword">const</span> + <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">T</span><span class="special">();</span> <span class="special">}</span> + + <span class="comment">// Generate BOOST_PROTO_MAX_ARITY overloads of the</span> + <span class="comment">// following function call operator.</span> +<span class="preprocessor">#define</span> <span class="identifier">BOOST_PROTO_LOCAL_MACRO</span><span class="special">(</span><span class="identifier">N</span><span class="special">,</span> <span class="identifier">typename_A</span><span class="special">,</span> <span class="identifier">A_const_ref</span><span class="special">,</span> <span class="identifier">A_const_ref_a</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)\</span> + <span class="keyword">template</span><span class="special"><</span><span class="identifier">typename_A</span><span class="special">(</span><span class="identifier">N</span><span class="special">)></span> <span class="special">\</span> + <span class="identifier">T</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">A_const_ref_a</span><span class="special">(</span><span class="identifier">N</span><span class="special">))</span> <span class="keyword">const</span> <span class="special">\</span> + <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">a</span><span class="special">(</span><span class="identifier">N</span><span class="special">));</span> <span class="special">}</span> +<span class="preprocessor">#define</span> <span class="identifier">BOOST_PROTO_LOCAL_a</span> <span class="identifier">BOOST_PROTO_a</span> +<span class="preprocessor">#include</span> <span class="identifier">BOOST_PROTO_LOCAL_ITERATE</span><span class="special">()</span> +<span class="special">};</span> + +<span class="comment">// Generate BOOST_PROTO_MAX_ARITY-1 overloads of the</span> +<span class="comment">// following construct() function template.</span> +<span class="preprocessor">#define</span> <span class="identifier">M0</span><span class="special">(</span><span class="identifier">N</span><span class="special">,</span> <span class="identifier">typename_A</span><span class="special">,</span> <span class="identifier">A_const_ref</span><span class="special">,</span> <span class="identifier">A_const_ref_a</span><span class="special">,</span> <span class="identifier">ref_a</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="identifier">typename_A</span><span class="special">(</span><span class="identifier">N</span><span class="special">)></span> <span class="special">\</span> +<span class="keyword">typename</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span> <span class="special">\</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">lambda_domain</span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">construct_helper</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">A_const_ref</span><span class="special">(</span><span class="identifier">N</span><span class="special">)</span> <span class="special">\</span> +<span class="special">>::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="special">\</span> +<span class="identifier">construct</span><span class="special">(</span><span class="identifier">A_const_ref_a</span><span class="special">(</span><span class="identifier">N</span><span class="special">))</span> <span class="special">\</span> +<span class="special">{</span> <span class="special">\</span> + <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">make_expr</span><span class="special"><</span> <span class="special">\</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">function</span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">lambda_domain</span> <span class="special">\</span> + <span class="special">>(</span> <span class="special">\</span> + <span class="identifier">construct_helper</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span> <span class="special">\</span> + <span class="special">,</span> <span class="identifier">ref_a</span><span class="special">(</span><span class="identifier">N</span><span class="special">)</span> <span class="special">\</span> + <span class="special">);</span> <span class="special">\</span> +<span class="special">}</span> +<span class="identifier">BOOST_PROTO_REPEAT_FROM_TO</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="identifier">BOOST_PROTO_MAX_ARITY</span><span class="special">,</span> <span class="identifier">M0</span><span class="special">)</span> +<span class="preprocessor">#undef</span> <span class="identifier">M0</span> + +<span class="keyword">struct</span> <span class="identifier">S</span> +<span class="special">{</span> + <span class="identifier">S</span><span class="special">()</span> <span class="special">{}</span> + <span class="identifier">S</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"S("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">","</span> <span class="special"><<</span> <span class="identifier">c</span> <span class="special"><<</span> <span class="string">")\n"</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="comment">// Create some lambda objects and immediately</span> + <span class="comment">// invoke them by applying their operator():</span> + <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="number">2</span><span class="special">)</span> <span class="special">/</span> <span class="number">4</span> <span class="special">)(</span><span class="number">42</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 11</span> + + <span class="keyword">int</span> <span class="identifier">j</span> <span class="special">=</span> <span class="special">(</span> <span class="special">(-(</span><span class="identifier">_1</span> <span class="special">+</span> <span class="number">2</span><span class="special">))</span> <span class="special">/</span> <span class="number">4</span> <span class="special">)(</span><span class="number">42</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">j</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints -11</span> + + <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="special">(</span> <span class="special">(</span><span class="number">4</span> <span class="special">-</span> <span class="identifier">_2</span><span class="special">)</span> <span class="special">*</span> <span class="number">3</span> <span class="special">)(</span><span class="number">42</span><span class="special">,</span> <span class="number">3.14</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">d</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 2.58</span> + + <span class="comment">// check non-const ref terminals</span> + <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">_1</span> <span class="special"><<</span> <span class="string">" -- "</span> <span class="special"><<</span> <span class="identifier">_2</span> <span class="special"><<</span> <span class="char">'\n'</span><span class="special">)(</span><span class="number">42</span><span class="special">,</span> <span class="string">"Life, the Universe and Everything!"</span><span class="special">);</span> + <span class="comment">// prints "42 -- Life, the Universe and Everything!"</span> + + <span class="comment">// "Nullary" lambdas work too</span> + <span class="keyword">int</span> <span class="identifier">k</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">val</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">val</span><span class="special">(</span><span class="number">2</span><span class="special">))();</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">k</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 3</span> + + <span class="comment">// check array indexing for kicks</span> + <span class="keyword">int</span> <span class="identifier">integers</span><span class="special">[</span><span class="number">5</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="number">0</span><span class="special">};</span> + <span class="special">(</span><span class="identifier">var</span><span class="special">(</span><span class="identifier">integers</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> <span class="special">=</span> <span class="number">2</span><span class="special">)();</span> + <span class="special">(</span><span class="identifier">var</span><span class="special">(</span><span class="identifier">integers</span><span class="special">)[</span><span class="identifier">_1</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">_1</span><span class="special">)(</span><span class="number">3</span><span class="special">);</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">integers</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 2</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">integers</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 3</span> + + <span class="comment">// Now use a lambda with an STL algorithm!</span> + <span class="keyword">int</span> <span class="identifier">rgi</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">};</span> + <span class="keyword">char</span> <span class="identifier">rgc</span><span class="special">[</span><span class="number">4</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="char">'a'</span><span class="special">,</span><span class="char">'b'</span><span class="special">,</span><span class="char">'c'</span><span class="special">,</span><span class="char">'d'</span><span class="special">};</span> + <span class="identifier">S</span> <span class="identifier">rgs</span><span class="special">[</span><span class="number">4</span><span class="special">];</span> + + <span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">rgi</span><span class="special">,</span> <span class="identifier">rgi</span><span class="special">+</span><span class="number">4</span><span class="special">,</span> <span class="identifier">rgc</span><span class="special">,</span> <span class="identifier">rgs</span><span class="special">,</span> <span class="identifier">construct</span><span class="special"><</span><span class="identifier">S</span><span class="special">>(</span><span class="identifier">_1</span><span class="special">,</span> <span class="identifier">_2</span><span class="special">));</span> + <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="boost_proto.users_guide.examples.checked_calc"></a><a class="link" href="users_guide.html#boost_proto.users_guide.examples.checked_calc" title="Checked Calculator: A Simple Example of External Transforms">Checked + Calculator: A Simple Example of External Transforms</a> +</h4></div></div></div> +<p> + This is an advanced example that shows how to externally parameterize a + grammar's transforms. It defines a calculator EDSL with a grammar that + can perform either checked or unchecked arithmetic. + </p> +<p> +</p> +<pre class="programlisting"><span class="comment">// Copyright 2011 Eric Niebler. Distributed under the Boost</span> +<span class="comment">// Software License, Version 1.0. (See accompanying file</span> +<span class="comment">// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</span> +<span class="comment">//</span> +<span class="comment">// This is an example of how to specify a transform externally so</span> +<span class="comment">// that a single grammar can be used to drive multiple differnt</span> +<span class="comment">// calculations. In particular, it defines a calculator grammar</span> +<span class="comment">// that computes the result of an expression with either checked</span> +<span class="comment">// or non-checked division.</span> + +<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</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">assert</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">mpl</span><span class="special">/</span><span class="keyword">int</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">mpl</span><span class="special">/</span><span class="identifier">next</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">mpl</span><span class="special">/</span><span class="identifier">min_max</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">container</span><span class="special">/</span><span class="identifier">vector</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">container</span><span class="special">/</span><span class="identifier">generation</span><span class="special">/</span><span class="identifier">make_vector</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">proto</span><span class="special">/</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> +<span class="keyword">namespace</span> <span class="identifier">mpl</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">proto</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">;</span> +<span class="keyword">namespace</span> <span class="identifier">fusion</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="comment">// The argument placeholder type</span> +<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">placeholder</span> <span class="special">:</span> <span class="identifier">I</span> <span class="special">{};</span> + +<span class="comment">// Give each rule in the grammar a "name". This is so that we</span> +<span class="comment">// can easily dispatch on it later.</span> +<span class="keyword">struct</span> <span class="identifier">calc_grammar</span><span class="special">;</span> +<span class="keyword">struct</span> <span class="identifier">divides_rule</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">divides</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> <span class="special">{};</span> + +<span class="comment">// Use external transforms in calc_gramar</span> +<span class="keyword">struct</span> <span class="identifier">calc_grammar</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">at</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_state</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span><span class="special">)</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">convertible_to</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">minus</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">,</span> <span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> + <span class="special">></span> + <span class="comment">// Note that we don't specify how division nodes are</span> + <span class="comment">// handled here. Proto::external_transform is a placeholder</span> + <span class="comment">// for an actual transform.</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">divides_rule</span> + <span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">external_transform</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">E</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">calc_expr</span><span class="special">;</span> +<span class="keyword">struct</span> <span class="identifier">calc_domain</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special"><</span><span class="identifier">calc_expr</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">E</span><span class="special">></span> +<span class="keyword">struct</span> <span class="identifier">calc_expr</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><</span><span class="identifier">E</span><span class="special">,</span> <span class="identifier">calc_expr</span><span class="special"><</span><span class="identifier">E</span><span class="special">>,</span> <span class="identifier">calc_domain</span><span class="special">></span> +<span class="special">{</span> + <span class="identifier">calc_expr</span><span class="special">(</span><span class="identifier">E</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">e</span> <span class="special">=</span> <span class="identifier">E</span><span class="special">())</span> <span class="special">:</span> <span class="identifier">calc_expr</span><span class="special">::</span><span class="identifier">proto_extends</span><span class="special">(</span><span class="identifier">e</span><span class="special">)</span> <span class="special">{}</span> +<span class="special">};</span> + +<span class="identifier">calc_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</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="number">0</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="identifier">_1</span><span class="special">;</span> +<span class="identifier">calc_expr</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special"><</span><span class="identifier">placeholder</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="number">1</span><span class="special">></span> <span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="identifier">_2</span><span class="special">;</span> + +<span class="comment">// Use proto::external_transforms to map from named grammar rules to</span> +<span class="comment">// transforms.</span> +<span class="keyword">struct</span> <span class="identifier">non_checked_division</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">external_transforms</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> <span class="identifier">divides_rule</span><span class="special">,</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">_default</span><span class="special"><</span><span class="identifier">calc_grammar</span><span class="special">></span> <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">division_by_zero</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span> <span class="special">{};</span> + +<span class="keyword">struct</span> <span class="identifier">do_checked_divide</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable</span> +<span class="special">{</span> + <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">result_type</span><span class="special">;</span> + <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">left</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">right</span><span class="special">)</span> <span class="keyword">const</span> + <span class="special">{</span> + <span class="keyword">if</span> <span class="special">(</span><span class="identifier">right</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">throw</span> <span class="identifier">division_by_zero</span><span class="special">();</span> + <span class="keyword">return</span> <span class="identifier">left</span> <span class="special">/</span> <span class="identifier">right</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// Use proto::external_transforms again, this time to map the divides_rule</span> +<span class="comment">// to a transforms that performs checked division.</span> +<span class="keyword">struct</span> <span class="identifier">checked_division</span> + <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">external_transforms</span><span class="special"><</span> + <span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span> + <span class="identifier">divides_rule</span> + <span class="special">,</span> <span class="identifier">do_checked_divide</span><span class="special">(</span><span class="identifier">calc_grammar</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_left</span><span class="special">),</span> <span class="identifier">calc_grammar</span><span class="special">(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_right</span><span class="special">))</span> + <span class="special">></span> + <span class="special">></span> +<span class="special">{};</span> + +<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> +<span class="special">{</span> + <span class="identifier">non_checked_division</span> <span class="identifier">non_checked</span><span class="special">;</span> + <span class="keyword">int</span> <span class="identifier">result2</span> <span class="special">=</span> <span class="identifier">calc_grammar</span><span class="special">()(</span><span class="identifier">_1</span> <span class="special">/</span> <span class="identifier">_2</span><span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">make_vector</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">2</span><span class="special">),</span> <span class="identifier">non_checked</span><span class="special">);</span> + <span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">result2</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> + + <span class="keyword">try</span> + <span class="special">{</span> + <span class="identifier">checked_division</span> <span class="identifier">checked</span><span class="special">;</span> + <span class="comment">// This should throw</span> + <span class="keyword">int</span> <span class="identifier">result3</span> <span class="special">=</span> <span class="identifier">calc_grammar</span><span class="special">()(</span><span class="identifier">_1</span> <span class="special">/</span> <span class="identifier">_2</span><span class="special">,</span> <span class="identifier">fusion</span><span class="special">::</span><span class="identifier">make_vector</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> <span class="identifier">checked</span><span class="special">);</span> + <span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span> <span class="comment">// shouldn't get here!</span> + <span class="special">}</span> + <span class="keyword">catch</span><span class="special">(</span><span class="identifier">division_by_zero</span><span class="special">)</span> + <span class="special">{</span> + <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"caught division by zero!\n"</span><span class="special">;</span> + <span class="special">}</span> +<span class="special">}</span> +</pre> +<p> + </p> +</div> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.resources"></a><a class="link" href="users_guide.html#boost_proto.users_guide.resources" title="Background and Resources">Background and Resources</a> +</h3></div></div></div> +<p> + Proto was initially developed as part of <a href="../../../libs/xpressive/index.html" target="_top">Boost.Xpressive</a> + to simplify the job of transforming an expression template into an executable + finite state machine capable of matching a regular expression. Since then, + Proto has found application in the redesigned and improved Spirit-2 and the + related Karma library. As a result of these efforts, Proto evolved into a + generic and abstract grammar and tree transformation framework applicable + in a wide variety of EDSL scenarios. + </p> +<p> + The grammar and tree transformation framework is modeled on Spirit's grammar + and semantic action framework. The expression tree data structure is similar + to Fusion data structures in many respects, and is interoperable with Fusion's + iterators and algorithms. + </p> +<p> + The syntax for the grammar-matching features of <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><></span></code> is inspired by MPL's lambda expressions. + </p> +<p> + The idea for using function types for Proto's composite transforms is inspired + by Aleksey Gurtovoy's <a href="http://lists.boost.org/Archives/boost/2002/11/39718.php" target="_top">"round" + lambda</a> notation. + </p> +<h5> +<a name="boost_proto.users_guide.resources.h0"></a> + <span><a name="boost_proto.users_guide.resources.references"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.resources.references">References</a> + </h5> +<div class="blockquote"><blockquote class="blockquote"><p> + <a name="boost_proto.users_guide.resources.SYB"></a>Ren, D. and Erwig, + M. 2006. A generic recursion toolbox for Haskell or: scrap your boilerplate + systematically. In <span class="emphasis"><em>Proceedings of the 2006 ACM SIGPLAN Workshop + on Haskell</em></span> (Portland, Oregon, USA, September 17 - 17, 2006). + Haskell '06. ACM, New York, NY, 13-24. DOI=<a href="http://doi.acm.org/10.1145/1159842.1159845" target="_top">http://doi.acm.org/10.1145/1159842.1159845</a> + </p></blockquote></div> +<h5> +<a name="boost_proto.users_guide.resources.h1"></a> + <span><a name="boost_proto.users_guide.resources.further_reading"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.resources.further_reading">Further + Reading</a> + </h5> +<p> + A technical paper about an earlier version of Proto was accepted into the + <a href="http://lcsd.cs.tamu.edu/2007/" target="_top">ACM SIGPLAN Symposium on Library-Centric + Software Design LCSD'07</a>, and can be found at <a href="http://lcsd.cs.tamu.edu/2007/final/1/1_Paper.pdf" target="_top">http://lcsd.cs.tamu.edu/2007/final/1/1_Paper.pdf</a>. + The tree transforms described in that paper differ from what exists today. + </p> +</div> +<div class="section"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="boost_proto.users_guide.glossary"></a><a class="link" href="users_guide.html#boost_proto.users_guide.glossary" title="Glossary">Glossary</a> +</h3></div></div></div> +<div class="variablelist"> +<p class="title"><b></b></p> +<dl> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.callable_transform"></a> callable transform</span></dt> +<dd><p> + A transform of the form <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">A0</span><span class="special">,</span><span class="identifier">A1</span><span class="special">,...)</span></code> (i.e., a function type) where + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_callable</span><span class="special"><</span><span class="identifier">R</span><span class="special">>::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">true</span></code>. + <code class="computeroutput"><span class="identifier">R</span></code> is treated as a polymorphic + function object and the arguments are treated as transforms that yield + the arguments to the function object. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.context"></a> context</span></dt> +<dd><p> + In Proto, the term <span class="emphasis"><em>context</em></span> refers to an object + that can be passed, along with an expression to evaluate, to the <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code> + function. The context determines how the expression is evaluated. All + context structs define a nested <code class="computeroutput"><span class="identifier">eval</span><span class="special"><></span></code> template that, when instantiated + with a node tag type (e.g., <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">plus</span></code>), + is a binary polymorphic function object that accepts an expression + of that type and the context object. In this way, contexts associate + behaviors with expression nodes. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.domain"></a> domain</span></dt> +<dd><p> + In Proto, the term <span class="emphasis"><em>domain</em></span> refers to a type that + associates expressions within that domain with a <span class="emphasis"><em>generator</em></span> + for that domain and optionally a <span class="emphasis"><em>grammar</em></span> for the + domain. Domains are used primarily to imbue expressions within that + domain with additional members and to restrict Proto's operator overloads + such that expressions not conforming to the domain's grammar are never + created. Domains are empty structs that inherit from <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special"><></span></code>. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.dsl"></a> domain-specific language</span></dt> +<dd><p> + A programming language that targets a particular problem space by providing + programming idioms, abstractions and constructs that match the constructs + within that problem space. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.edsl"></a> embedded domain-specific language</span></dt> +<dd><p> + A domain-specific language implemented as a library. The language in + which the library is written is called the "host" language, + and the language implemented by the library is called the "embedded" + language. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.expression"></a> expression</span></dt> +<dd><p> + In Proto, an <span class="emphasis"><em>expression</em></span> is a heterogeneous tree + where each node is either an instantiation of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">expr</span><span class="special"><></span></code>, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">basic_expr</span><span class="special"><></span></code> or some type that is an extension + (via <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special"><></span></code> + or <code class="computeroutput"><span class="identifier">BOOST_PROTO_EXTENDS</span><span class="special">()</span></code>) of such an instantiation. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.expression_template"></a> expression template</span></dt> +<dd><p> + A C++ technique using templates and operator overloading to cause expressions + to build trees that represent the expression for lazy evaluation later, + rather than evaluating the expression eagerly. Some C++ libraries use + expression templates to build embedded domain-specific languages. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.generator"></a> generator</span></dt> +<dd><p> + In Proto, a <span class="emphasis"><em>generator</em></span> is a unary polymorphic function + object that you specify when defining a <span class="emphasis"><em>domain</em></span>. + After constructing a new expression, Proto passes the expression to + your domain's generator for further processing. Often, the generator + wraps the expression in an extension wrapper that adds additional members + to it. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.grammar"></a> grammar</span></dt> +<dd><p> + In Proto, a <span class="emphasis"><em>grammar</em></span> is a type that describes a + subset of Proto expression types. Expressions in a domain must conform + to that domain's grammar. The <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">matches</span><span class="special"><></span></code> metafunction evaluates whether + an expression type matches a grammar. Grammars are either primitives + such as <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span></code>, composites such as <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">plus</span><span class="special"><></span></code>, + control structures such as <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">or_</span><span class="special"><></span></code>, or some type derived from + a grammar. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.object_transform"></a> object transform</span></dt> +<dd><p> + A transform of the form <code class="computeroutput"><span class="identifier">R</span><span class="special">(</span><span class="identifier">A0</span><span class="special">,</span><span class="identifier">A1</span><span class="special">,...)</span></code> (i.e., a function type) where + <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">is_callable</span><span class="special"><</span><span class="identifier">R</span><span class="special">>::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">false</span></code>. + <code class="computeroutput"><span class="identifier">R</span></code> is treated as the + type of an object to construct and the arguments are treated as transforms + that yield the parameters to the constructor. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.polymorphic_function_object"></a> polymorphic function object</span></dt> +<dd><p> + An instance of a class type with an overloaded function call operator + and a nested <code class="computeroutput"><span class="identifier">result_type</span></code> + typedef or <code class="computeroutput"><span class="identifier">result</span><span class="special"><></span></code> + template for calculating the return type of the function call operator. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.primitive_transform"></a> primitive transform</span></dt> +<dd><p> + A type that defines a kind of polymorphic function object that takes + three arguments: expression, state, and data. Primitive transforms + can be used to compose callable transforms and object transforms. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.subdomain"></a> sub-domain</span></dt> +<dd><p> + A sub-domain is a domain that declares another domain as its super-domain. + Expressions in sub-domains can be combined with expressions in the + super-domain, and the resulting expression is in the super-domain. + </p></dd> +<dt><span class="term"> <a name="boost_proto.users_guide.glossary.transform"></a> transform</span></dt> +<dd><p> + Transforms are used to manipulate expression trees. They come in three + flavors: primitive transforms, callable transforms, or object transforms. + A transform <code class="computeroutput"><em class="replaceable"><code>T</code></em></code> can be made into + a ternary polymorphic function object with <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><></span></code>, as in <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">when</span><span class="special"><</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_</span><span class="special">,</span> <em class="replaceable"><code>T</code></em><span class="special">></span></code>. + Such a function object accepts <span class="emphasis"><em>expression</em></span>, <span class="emphasis"><em>state</em></span>, + and <span class="emphasis"><em>data</em></span> parameters, and computes a result from + them. + </p></dd> +</dl> +</div> +</div> +<div class="footnotes"> +<br><hr width="100" align="left"> +<div class="footnote"><p><sup>[<a id="ftn.boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.f0" href="#boost_proto.users_guide.front_end.customizing_expressions_in_your_domain.per_domain_as_child.f0" class="para">4</a>] </sup> + It's not always possible to hold something by value. By default, <code class="computeroutput"><a class="link" href="../boost/proto/as_expr_id1527385.html" title="Function as_expr">proto::as_expr()</a></code> makes an exception + for functions, abstract types, and iostreams (types derived from <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ios_base</span></code>). These objects are held + by reference. All others are held by value, even arrays. + </p></div> +<div class="footnote"><p><sup>[<a id="ftn.boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity.f0" href="#boost_proto.users_guide.back_end.expression_transformation.example__calculator_arity.f0" class="para">5</a>] </sup> + This error message was generated with Microsoft Visual C++ 9.0. Different + compilers will emit different messages with varying degrees of readability. + </p></div> +</div> +</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 © 2008 Eric Niebler<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="../proto.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> +</div> +</body> +</html> |