• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Manual</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../yap.html" title="Chapter 47. Boost.YAP">
10<link rel="prev" href="../yap.html" title="Chapter 47. Boost.YAP">
11<link rel="next" href="concepts.html" title="Concepts">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="../yap.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../yap.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="concepts.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="boost_yap.manual"></a><a class="link" href="manual.html" title="Manual">Manual</a>
29</h2></div></div></div>
30<div class="toc"><dl class="toc">
31<dt><span class="section"><a href="manual.html#boost_yap.manual.an_expression_template_primer">An Expression
32      Template Primer</a></span></dt>
33<dt><span class="section"><a href="manual.html#boost_yap.manual.the_yap_way">The YAP Way</a></span></dt>
34<dt><span class="section"><a href="manual.html#boost_yap.manual.expressions">Expressions</a></span></dt>
35<dt><span class="section"><a href="manual.html#boost_yap.manual.mix_and_match_expression_templates">Mix-and-Match
36      Expression Templates</a></span></dt>
37<dt><span class="section"><a href="manual.html#boost_yap.manual.kinds_of_expressions">Kinds of Expressions</a></span></dt>
38<dt><span class="section"><a href="manual.html#boost_yap.manual.operators">Operators</a></span></dt>
39<dt><span class="section"><a href="manual.html#boost_yap.manual.transforming_expressions">Transforming
40      Expressions</a></span></dt>
41<dt><span class="section"><a href="manual.html#boost_yap.manual.evaluating_expressions">Evaluating Expressions</a></span></dt>
42<dt><span class="section"><a href="manual.html#boost_yap.manual.operator_macros">Operator Macros</a></span></dt>
43<dt><span class="section"><a href="manual.html#boost_yap.manual.how_expression_operands_are_treated">How
44      Expression Operands Are Treated</a></span></dt>
45<dt><span class="section"><a href="manual.html#boost_yap.manual.printing">Printing</a></span></dt>
46<dt><span class="section"><a href="manual.html#boost_yap.manual.examples">Examples</a></span></dt>
47<dt><span class="section"><a href="manual.html#boost_yap.manual.header_organization">Header Organization</a></span></dt>
48<dt><span class="section"><a href="manual.html#boost_yap.manual.configuration">Configuration</a></span></dt>
49<dt><span class="section"><a href="manual.html#boost_yap.manual.object_code">Object Code</a></span></dt>
50</dl></div>
51<div class="section">
52<div class="titlepage"><div><div><h3 class="title">
53<a name="boost_yap.manual.an_expression_template_primer"></a><a class="link" href="manual.html#boost_yap.manual.an_expression_template_primer" title="An Expression Template Primer">An Expression
54      Template Primer</a>
55</h3></div></div></div>
56<p>
57        What are expression templates anyway? In short, expression templates are
58        templates that you write to capture expressions so that they can be transformed
59        and/or evaluated lazily.
60      </p>
61<p>
62        An example of normal C++ expression is:
63      </p>
64<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">+</span> <span class="number">8.0f</span>
65</pre>
66<p>
67        The compiler sees this and creates some representation of that expression
68        inside the compiler. This is typically an <a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" target="_top">abstract
69        syntax tree</a> (AST). The AST for the expression above might be:
70      </p>
71<p>
72        <span class="inlinemediaobject"><img src="../yap/img/ast.png" alt="ast"></span>
73      </p>
74<p>
75        This tree structure captures all the elements of the original C++ code. The
76        expression is a plus operation whose left side is a call to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span></code>
77        and whose right side is <code class="computeroutput"><span class="number">8.0f</span></code>.
78        The call to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span></code> is its own expression subtree consisting
79        of a call node and its argument node.
80      </p>
81<p>
82        A Boost.YAP version of this same tree is:
83      </p>
84<p>
85        <span class="inlinemediaobject"><img src="../yap/img/expr.png" alt="expr"></span>
86      </p>
87<p>
88        The <code class="computeroutput"><span class="keyword">operator</span><span class="special">+()</span></code>
89        is represented by a Boost.YAP expression whose kind is <code class="computeroutput"><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span></code>
90        and the call is represented by a Boost.YAP expression whose kind is <code class="computeroutput"><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span></code>.
91        Notice that the call expression has two terminals, one for the callable,
92        and one for its single argument.
93      </p>
94<p>
95        The type that holds this expression is:
96      </p>
97<p>
98</p>
99<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
100    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span><span class="special">,</span>
101    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
102        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
103            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">,</span>
104            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
105                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
106                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
107                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)&gt;</span>
108                <span class="special">&gt;,</span>
109                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
110                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
111                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span>
112                <span class="special">&gt;</span>
113            <span class="special">&gt;</span>
114        <span class="special">&gt;,</span>
115        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
116            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
117            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span>
118        <span class="special">&gt;</span>
119    <span class="special">&gt;</span>
120<span class="special">&gt;</span>
121</pre>
122<p>
123      </p>
124<p>
125        That looks like a big mess; let's unpack it. You might notice that the overall
126        shape is the same as the expression tree diagram above. We have tree-like
127        nesting of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span></code>
128        template instantiations.
129      </p>
130<p>
131        Here's the top-level <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span></code> again with its noisy guts removed:
132      </p>
133<p>
134</p>
135<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
136    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span><span class="special">,</span>
137    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
138</pre>
139<p>
140      </p>
141<pre class="programlisting"><span class="comment">// Left and right operand expressions ...</span>
142</pre>
143<p>
144</p>
145<pre class="programlisting">    <span class="special">&gt;</span>
146<span class="special">&gt;</span>
147</pre>
148<p>
149      </p>
150<p>
151        It has an <code class="computeroutput"><a class="link" href="../boost/yap/expr_kind.html" title="Type expr_kind">expr_kind</a></code>
152        of <code class="computeroutput"><span class="identifier">plus</span></code> as its first template
153        parameter (it's a non-type parameter); this indicates what kind of "node"
154        it is. In this case, the top level expression is analogous to our <code class="computeroutput"><span class="keyword">operator</span><span class="special">+()</span></code>
155        AST node. Its operands are the elements of its <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;&gt;</span></code> data member.
156      </p>
157<p>
158        The left operand to the top-level plus operation is itself a Boost.YAP expression
159        representing <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span></code>:
160      </p>
161<p>
162</p>
163<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
164    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">,</span>
165    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
166        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
167            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
168            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)&gt;</span>
169        <span class="special">&gt;,</span>
170        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
171            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
172            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span>
173        <span class="special">&gt;</span>
174    <span class="special">&gt;</span>
175<span class="special">&gt;,</span>
176</pre>
177<p>
178      </p>
179<p>
180        This expression is a call expression. The first operand to the call expression
181        is the callable entity, in this case a pointer to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span></code>.
182        The remaining operands are the arguments to pass to the callable; in this
183        case, there's only one operand after the callable, <code class="computeroutput"><span class="number">3.0</span></code>.
184      </p>
185<p>
186        The children of the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span></code> subexpression are terminals. This means
187        that they are leaf nodes in our notional AST.
188      </p>
189<p>
190        The right operand to the top-level plus operation is of course also a Boost.YAP
191        expression. It is also a terminal:
192      </p>
193<p>
194</p>
195<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
196    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
197    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span>
198<span class="special">&gt;</span>
199</pre>
200<p>
201      </p>
202<p>
203        Notice a couple of things here: 1) non-terminals (the top-level plus operation
204        and the call opertion in our example) have tuple elements that are <span class="bold"><strong>all</strong></span> Boost.YAP expressions, and 2) terminals have tuple
205        elements, <span class="bold"><strong>none of which</strong></span> are Boost.YAP expressions
206        (they're just normal types like <code class="computeroutput"><span class="keyword">float</span></code>
207        and <code class="computeroutput"><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)</span></code>).
208      </p>
209<div class="note"><table border="0" summary="Note">
210<tr>
211<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
212<th align="left">Note</th>
213</tr>
214<tr><td align="left" valign="top"><p>
215          From here on, I'll use the terms "expression" and "node"
216          interchangably, and I'll also use the terms "subexpression" and
217          "child" interchangably. Even though expression templates are
218          not identical to tree-based ASTs, they're close enough that the terminology
219          is interchangable without loss of meaning.
220        </p></td></tr>
221</table></div>
222<h5>
223<a name="boost_yap.manual.an_expression_template_primer.h0"></a>
224        <span class="phrase"><a name="boost_yap.manual.an_expression_template_primer.capturing_an_expression"></a></span><a class="link" href="manual.html#boost_yap.manual.an_expression_template_primer.capturing_an_expression">Capturing
225        an Expression</a>
226      </h5>
227<p>
228        If we want to capture an expression using Boost.YAP we have to do something
229        to let the compiler know not just to eagerly evaulate our expression, as
230        it does when it sees <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span>
231        <span class="special">+</span> <span class="number">8.0f</span></code>.
232      </p>
233<p>
234        To do this, we create <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.terminal"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span></code></a> expressions out of one
235        or more of the terminals in the expression we want to capture and evaluate
236        lazily. Here, I've declared a template alias to make that easier to type:
237      </p>
238<p>
239</p>
240<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
241<span class="keyword">using</span> <span class="identifier">term</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;;</span>
242</pre>
243<p>
244      </p>
245<p>
246        And here is how I might use that alias to create the terminal containing
247        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span></code>:
248      </p>
249<p>
250</p>
251<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
252    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span><span class="special">,</span>
253    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
254        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
255            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">,</span>
256            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span>
257                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
258                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
259                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)&gt;</span>
260                <span class="special">&gt;,</span>
261                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
262                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
263                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span>
264                <span class="special">&gt;</span>
265            <span class="special">&gt;</span>
266        <span class="special">&gt;,</span>
267        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
268            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
269            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;</span>
270        <span class="special">&gt;</span>
271    <span class="special">&gt;</span>
272<span class="special">&gt;</span>
273<span class="identifier">yap_expr</span> <span class="special">=</span> <span class="identifier">term</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)&gt;{{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">}}(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">+</span> <span class="number">8.0f</span><span class="special">;</span>
274</pre>
275<p>
276      </p>
277<p>
278        The reason I can then just call the terminal with a <code class="computeroutput"><span class="number">3.0</span></code>
279        argument and add <code class="computeroutput"><span class="number">8.0f</span></code> to the
280        result is that I'm taking a great big shortcut in this example by using Boost.YAP's
281        built-in example expression template, <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code>.
282        <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code> is a template with all
283        the operator overloads defined, including the call operator. Each operator
284        overload returns an <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code>,
285        which is why the <code class="computeroutput"><span class="special">+</span></code> in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span>
286        <span class="special">+</span> <span class="number">8.0f</span></code>
287        also works.
288      </p>
289<div class="note"><table border="0" summary="Note">
290<tr>
291<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
292<th align="left">Note</th>
293</tr>
294<tr><td align="left" valign="top">
295<p>
296          <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code> is great for example
297          code like what you see here, and it's great for small expression template
298          use cases that are essentially implementation details. You should write
299          your own expression templates for anything that is to be used in any other
300          context. The reason for this is that most of the time your expression template
301          system will not want to support all combinations of all possible operators
302          and function calls. For instance, code like this:
303        </p>
304<p>
305          (a + b) = c;
306        </p>
307<p>
308          is at least unusual, if not outright wrong. Where does <code class="computeroutput"><span class="identifier">c</span></code>
309          go? Into <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">b</span></code>, or into an expiring <code class="computeroutput"><span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span></code> temporary? What if <code class="computeroutput"><span class="identifier">a</span></code>
310          is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> and <code class="computeroutput"><span class="identifier">b</span></code>
311          is a <code class="computeroutput"><span class="identifier">FILE</span> <span class="special">*</span></code>?
312          <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code> doesn't care. You probably
313          want to design interfaces that are more carefully considered than the "everything
314          goes" style implied by using <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code>.
315        </p>
316</td></tr>
317</table></div>
318<p>
319        Boost.YAP comes with a handy <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code>
320        function. Calling it like this:
321      </p>
322<p>
323</p>
324<pre class="programlisting"><span class="identifier">print</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">yap_expr</span><span class="special">);</span>
325</pre>
326<p>
327      </p>
328<p>
329        Gives this output:
330      </p>
331<pre class="programlisting"><span class="identifier">expr</span><span class="special">&lt;+&gt;</span>
332    <span class="identifier">expr</span><span class="special">&lt;()&gt;</span>
333        <span class="identifier">term</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)&gt;[=</span><span class="number">1</span><span class="special">]</span>
334        <span class="identifier">term</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;[=</span><span class="number">3</span><span class="special">]</span>
335    <span class="identifier">term</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">&gt;[=</span><span class="number">8</span><span class="special">]</span>
336</pre>
337<p>
338        This is a lot more readable. I show this to you here to give you a more concise
339        view of the AST-like structure.
340      </p>
341<p>
342        (In case you're wondering why <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">sqrt</span></code>
343        is printed as the value <code class="computeroutput"><span class="number">1</span></code>, so
344        was I. Apparently, that's just what GCC prints for that. Weird.)
345      </p>
346<h5>
347<a name="boost_yap.manual.an_expression_template_primer.h1"></a>
348        <span class="phrase"><a name="boost_yap.manual.an_expression_template_primer.doing_something_useful_with_it"></a></span><a class="link" href="manual.html#boost_yap.manual.an_expression_template_primer.doing_something_useful_with_it">Doing
349        Something Useful With It</a>
350      </h5>
351<p>
352        Now we've seen a simple expression both described as a C++ AST and captured
353        as a Boost.YAP expression. This just introduces the expression template mechanism;
354        what do we do with it once we have an expression template? Consider one of
355        the examples from the intro:
356      </p>
357<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="special">{/*</span> <span class="special">...</span> <span class="special">*/};</span>
358<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v2</span> <span class="special">=</span> <span class="identifier">sort</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="special">|</span> <span class="identifier">unique</span><span class="special">;</span>
359</pre>
360<p>
361        The rest of the tutorial will explain in greater detail how Boost.YAP can
362        be used in situations like this, but the brief version is this:
363      </p>
364<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
365<li class="listitem">
366            Use Boost.YAP to capture an expression. In this case, something like
367            <code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">expr</span>
368            <span class="special">=</span> <span class="identifier">sort</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="special">|</span> <span class="identifier">unique</span><span class="special">;</span></code>.
369          </li>
370<li class="listitem">
371            Use the Boost.YAP <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
372            algorithm to transform the expression into what you want. In this case,
373            something like <code class="computeroutput"><span class="keyword">auto</span> <span class="identifier">desired_expr</span>
374            <span class="special">=</span> <span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">my_transform</span><span class="special">);</span></code>, which turns the concise form <code class="computeroutput"><span class="identifier">sort</span><span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="special">|</span> <span class="identifier">unique</span></code>
375            into the more verbose calls required by the standard algorithm APIs.
376            Note that the resulting expression can be transformed repeatedly if this
377            is desirable.
378          </li>
379<li class="listitem">
380            Evauate the final expression, either using <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>
381            or a call to <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
382            that transforms the final expression into an evaluated result.
383          </li>
384</ul></div>
385</div>
386<div class="section">
387<div class="titlepage"><div><div><h3 class="title">
388<a name="boost_yap.manual.the_yap_way"></a><a class="link" href="manual.html#boost_yap.manual.the_yap_way" title="The YAP Way">The YAP Way</a>
389</h3></div></div></div>
390<p>
391        There are certain idioms that Boost.YAP is written to support. Before getting
392        into the nuts and bolts of how Boost.YAP operates, let's define these idioms.
393      </p>
394<h5>
395<a name="boost_yap.manual.the_yap_way.h0"></a>
396        <span class="phrase"><a name="boost_yap.manual.the_yap_way._code__phrase_role__identifier__evaluate__phrase__phrase_role__special_____phrase__phrase_role__identifier__transform__phrase__phrase_role__special_______phrase___code_"></a></span><a class="link" href="manual.html#boost_yap.manual.the_yap_way._code__phrase_role__identifier__evaluate__phrase__phrase_role__special_____phrase__phrase_role__identifier__transform__phrase__phrase_role__special_______phrase___code_"><code class="computeroutput"><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">transform</span><span class="special">())</span></code></a>
397      </h5>
398<p>
399        This is the main idiom you'll see reinforced in the examples. The idea is
400        that you capture an expression:
401      </p>
402<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">expr_0</span> <span class="special">=</span> <span class="comment">/* ... */</span> <span class="special">;</span>
403</pre>
404<p>
405        then transform it one or more times:
406      </p>
407<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">expr_1</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr_0</span><span class="special">,</span> <span class="identifier">my_transform_1</span><span class="special">);</span>
408<span class="keyword">auto</span> <span class="identifier">expr_2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr_1</span><span class="special">,</span> <span class="identifier">my_transform_2</span><span class="special">);</span>
409<span class="comment">// ...</span>
410<span class="keyword">auto</span> <span class="identifier">expr_n</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr_n_minus_1</span><span class="special">,</span> <span class="identifier">my_transform_n</span><span class="special">);</span>
411</pre>
412<p>
413        and then finally you evaluate it:
414      </p>
415<pre class="programlisting"><span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_n</span><span class="special">);</span>
416</pre>
417<p>
418        Each call to <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> here produces a new <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a> that can subsequently
419        be transformed. This is conceptually similar to what happens inside many
420        compilers. Capturing the expression is analogous to the compiler's parse;
421        the transformations are analogous to optimization passes; and the evaluation
422        is analogous to code generation.
423      </p>
424<p>
425        This keeps the meaning of your code quite clear and easy to follow. For this
426        reason, I think you should try to use Boost.YAP in this way when you can.
427      </p>
428<h5>
429<a name="boost_yap.manual.the_yap_way.h1"></a>
430        <span class="phrase"><a name="boost_yap.manual.the_yap_way._code__phrase_role__identifier__transform__phrase__phrase_role__special______phrase___code__as_evaluate"></a></span><a class="link" href="manual.html#boost_yap.manual.the_yap_way._code__phrase_role__identifier__transform__phrase__phrase_role__special______phrase___code__as_evaluate"><code class="computeroutput"><span class="identifier">transform</span><span class="special">()</span></code>-as-evaluate</a>
431      </h5>
432<p>
433        This is a variant of <code class="computeroutput"><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">transform</span><span class="special">())</span></code>, where the <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>
434        call at the end is unnecessary, because the final (or perhaps only) transform
435        does all the evaluation we need.
436      </p>
437<p>
438        For instance, here is the <code class="computeroutput"><span class="identifier">get_arity</span></code>
439        transform object used in the <a class="link" href="manual.html#boost_yap.manual.examples.calc3" title="Calc3">Calc3</a>
440        example (don't worry too much about the implementation — we'll return
441        to this later in the docs in much greater detail):
442      </p>
443<p>
444</p>
445<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">get_arity</span>
446<span class="special">{</span>
447    <span class="comment">// Base case 1: Match a placeholder terminal, and return its arity as the</span>
448    <span class="comment">// result.</span>
449    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">&gt;</span>
450    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
451                                      <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;)</span>
452    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;;</span> <span class="special">}</span>
453
454    <span class="comment">// Base case 2: Match any other terminal.  Return 0; non-placeholders do</span>
455    <span class="comment">// not contribute to arity.</span>
456    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
457    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span> <span class="identifier">T</span> <span class="special">&amp;&amp;)</span>
458    <span class="special">{</span>
459        <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
460        <span class="keyword">return</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">;</span>
461    <span class="special">}</span>
462
463    <span class="comment">// Recursive case: Match any expression not covered above, and return the</span>
464    <span class="comment">// maximum of its children's arities.</span>
465    <span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Arg</span><span class="special">&gt;</span>
466    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">&gt;,</span> <span class="identifier">Arg</span> <span class="special">&amp;&amp;...</span> <span class="identifier">arg</span><span class="special">)</span>
467    <span class="special">{</span>
468        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">(</span>
469            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span>
470                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span>
471                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Arg</span><span class="special">&gt;(</span><span class="identifier">arg</span><span class="special">)),</span>
472                    <span class="identifier">get_arity</span><span class="special">{}</span>
473                <span class="special">)...</span>
474            <span class="special">)</span>
475        <span class="special">);</span>
476    <span class="special">}</span>
477<span class="special">};</span>
478</pre>
479<p>
480      </p>
481<p>
482        Here is how this might be used:
483      </p>
484<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">*</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">;</span>
485<span class="keyword">auto</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">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">get_arity</span><span class="special">{});</span>
486<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">arity</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="string">"Called with wrong number of args."</span><span class="special">);</span>
487</pre>
488<p>
489        In this case, <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> produces a non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
490        value, all by itself. We got our result without ever needing to call <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>.
491      </p>
492<div class="note"><table border="0" summary="Note">
493<tr>
494<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
495<th align="left">Note</th>
496</tr>
497<tr><td align="left" valign="top"><p>
498          Whether <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> returns an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
499          or non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
500          is entirely up to the caller. The transform object passed as the second
501          argument to <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> defines what <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>'s return type will be.
502        </p></td></tr>
503</table></div>
504</div>
505<div class="section">
506<div class="titlepage"><div><div><h3 class="title">
507<a name="boost_yap.manual.expressions"></a><a class="link" href="manual.html#boost_yap.manual.expressions" title="Expressions">Expressions</a>
508</h3></div></div></div>
509<p>
510        Boost.YAP consists of expressions and functions that operate on them. A function
511        that takes an expression will accept any type that models the <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
512        concept.
513      </p>
514<p>
515        For a type <code class="computeroutput"><span class="identifier">T</span></code> to model the
516        <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a> concept,
517        <code class="computeroutput"><span class="identifier">T</span></code> must contain at least an
518        <code class="computeroutput"><a class="link" href="../boost/yap/expr_kind.html" title="Type expr_kind">expr_kind</a></code>
519        (terminal, plus-operation, etc.) and a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;&gt;</span></code> of values. That's it.
520      </p>
521<div class="note"><table border="0" summary="Note">
522<tr>
523<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
524<th align="left">Note</th>
525</tr>
526<tr><td align="left" valign="top"><p>
527          The <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;&gt;</span></code>
528          of values is constrained, based on the kind of the expression; see the
529          full <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a> documentation
530          for details.
531        </p></td></tr>
532</table></div>
533<p>
534        Here's an example of an expression:
535      </p>
536<p>
537</p>
538<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
539<span class="keyword">struct</span> <span class="identifier">minimal_expr</span>
540<span class="special">{</span>
541    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
542
543    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
544<span class="special">};</span>
545</pre>
546<p>
547      </p>
548<p>
549        That's a template that models <a class="link" href="concepts.html#boost_yap.concepts.expressiontemplate">ExpressionTemplate</a>.
550        Instantiated with the proper template parameters, it produces <a class="link" href="concepts.html#boost_yap.concepts.expression">Expressions</a>.
551      </p>
552<p>
553        Ok, so it's not that interesting by itself — <code class="computeroutput"><span class="identifier">minimal_expr</span></code>
554        has no operations defined for it. But we can still use it with the Boost.YAP
555        functions that take an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>.
556        Let's make a Boost.YAP plus-expression manually:
557      </p>
558<p>
559</p>
560<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">left</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">);</span>
561<span class="keyword">auto</span> <span class="identifier">right</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="number">41</span><span class="special">);</span>
562
563<span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_expression</span><span class="special">&lt;</span>
564    <span class="identifier">minimal_expr</span><span class="special">,</span>
565    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span>
566<span class="special">&gt;(</span><span class="identifier">left</span><span class="special">,</span> <span class="identifier">right</span><span class="special">);</span>
567</pre>
568<p>
569      </p>
570<p>
571        If we evaluate it using <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>,
572        it does what you would expect:
573      </p>
574<p>
575</p>
576<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
577
578<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// prints "42"</span>
579</pre>
580<p>
581      </p>
582<p>
583        One more thing. It is important to remember that Boost.YAP expressions are
584        all-lazy, all the time. There is no auto-evaluation of a Boost.YAP expression
585        like there is with normal C++ expressions. If you want your expressions to
586        be evaluated, you must call <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>,
587        or define non-lazy operations that force evaluation where and when you want
588        it. This last approach is usually the right one, and there are lots of examples
589        of how to do this in the <a class="link" href="manual.html#boost_yap.manual.examples" title="Examples">Examples</a>
590        section. In particular, checkout the <a class="link" href="manual.html#boost_yap.manual.examples.lazy_vector" title="Lazy Vector">Lazy
591        Vector</a> and <a class="link" href="manual.html#boost_yap.manual.examples.tarray" title="TArray">TArray</a>
592        examples.
593      </p>
594</div>
595<div class="section">
596<div class="titlepage"><div><div><h3 class="title">
597<a name="boost_yap.manual.mix_and_match_expression_templates"></a><a class="link" href="manual.html#boost_yap.manual.mix_and_match_expression_templates" title="Mix-and-Match Expression Templates">Mix-and-Match
598      Expression Templates</a>
599</h3></div></div></div>
600<p>
601        Because Boost.YAP operates on <a class="link" href="concepts.html#boost_yap.concepts.expression">Expressions</a>,
602        it is possible to mix and match <a class="link" href="concepts.html#boost_yap.concepts.expression">Expressions</a>
603        that are instantiations of different templates.
604      </p>
605<p>
606        Here's why that's important. Say we have two types in a library. <code class="computeroutput"><span class="identifier">S</span></code> is a string type, and <code class="computeroutput"><span class="identifier">M</span></code>
607        is a matrix type. In the code here, <code class="computeroutput"><span class="identifier">s</span></code>
608        and <code class="computeroutput"><span class="identifier">m</span></code> are objects of types
609        <code class="computeroutput"><span class="identifier">S</span></code> and <code class="computeroutput"><span class="identifier">M</span></code>
610        respectively. Say we also have typical operator overloads for these types,
611        so <code class="computeroutput"><span class="identifier">m</span> <span class="special">*</span>
612        <span class="identifier">m</span></code> and <code class="computeroutput"><span class="identifier">s</span><span class="special">[</span><span class="number">0</span><span class="special">]</span></code>
613        are well-formed expressions, but <code class="computeroutput"><span class="identifier">m</span><span class="special">[</span><span class="number">0</span><span class="special">]</span></code>
614        and <code class="computeroutput"><span class="identifier">s</span> <span class="special">*</span>
615        <span class="identifier">s</span></code> are not.
616      </p>
617<p>
618        To use these with Boost.YAP I might write an expression template for each:
619      </p>
620<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;...&gt;</span>
621<span class="keyword">struct</span> <span class="identifier">m_expr</span>
622<span class="special">{</span>
623    <span class="comment">// ...</span>
624<span class="special">};</span>
625
626<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">times</span><span class="special">,</span> <span class="identifier">m_expr</span><span class="special">,</span> <span class="identifier">m_expr</span><span class="special">)</span>
627
628<span class="keyword">template</span> <span class="special">&lt;...&gt;</span>
629<span class="keyword">struct</span> <span class="identifier">s_expr</span>
630<span class="special">{</span>
631    <span class="comment">// ...</span>
632    <span class="identifier">BOOST_YAP_USER_SUBSCRIPT_OPERATOR</span><span class="special">(::</span><span class="identifier">s_expr</span><span class="special">)</span>
633<span class="special">};</span>
634</pre>
635<p>
636        With this, I might write a Boost.YAP expression like:
637      </p>
638<pre class="programlisting"><span class="identifier">some_expr_producing_func</span><span class="special">(</span><span class="identifier">S</span><span class="special">(</span><span class="string">"my_matrix"</span><span class="special">))</span> <span class="special">*</span> <span class="identifier">some_matrix</span>
639</pre>
640<p>
641        I can transform this expression however I like, and do not have to worry
642        about the fact that it contains expressions instantiated from different templates.
643      </p>
644<p>
645        If Boost.YAP required an expression to be instantiated from a single expression
646        template <code class="computeroutput"><span class="identifier">expr</span><span class="special">&lt;&gt;</span></code>,
647        <code class="computeroutput"><span class="identifier">expr</span><span class="special">&lt;&gt;</span></code>
648        would have to have both operators. This means that all of a sudden <code class="computeroutput"><span class="identifier">s</span> <span class="special">*</span> <span class="identifier">s</span></code>
649        and <code class="computeroutput"><span class="identifier">m</span><span class="special">[</span><span class="number">0</span><span class="special">]</span></code> would be
650        well-formed expressions within a Boost.YAP expression, but <span class="bold"><strong>not</strong></span>
651        for the real types <code class="computeroutput"><span class="identifier">S</span></code> and
652        <code class="computeroutput"><span class="identifier">M</span></code> respectively. That would
653        be super weird.
654      </p>
655</div>
656<div class="section">
657<div class="titlepage"><div><div><h3 class="title">
658<a name="boost_yap.manual.kinds_of_expressions"></a><a class="link" href="manual.html#boost_yap.manual.kinds_of_expressions" title="Kinds of Expressions">Kinds of Expressions</a>
659</h3></div></div></div>
660<p>
661        Most of the expression kinds are the overloadable operators (<code class="computeroutput"><span class="keyword">operator</span><span class="special">!()</span></code>,
662        <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;=()</span></code>,
663        etc.), See <code class="computeroutput"><a class="link" href="../boost/yap/expr_kind.html" title="Type expr_kind">expr_kind</a></code>
664        for the full list.
665      </p>
666<p>
667        There are three special kinds of expressions:
668      </p>
669<div class="variablelist">
670<p class="title"><b></b></p>
671<dl class="variablelist">
672<dt><span class="term"><a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.terminal"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span></code></a></span></dt>
673<dd><p>
674              A terminal contains a non-Expression value, and represents a leaf-node
675              in an expression tree. A terminal may have a <code class="computeroutput"><a class="link" href="../boost/yap/placeholder.html" title="Struct template placeholder">placeholder&lt;&gt;</a></code>
676              value, in which case it acts as a placeholder.
677            </p></dd>
678<dt><span class="term"><a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.if_else"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">if_else</span></code></a></span></dt>
679<dd><p>
680              An <code class="computeroutput"><span class="identifier">if_else</span></code> expression
681              is analogous to the C++ ternary operator (<code class="computeroutput"><span class="special">?:</span></code>).
682              It's up to you to make sure that the conditional expression given to
683              <code class="computeroutput"><span class="identifier">if_else</span></code> can be converted
684              to <code class="computeroutput"><span class="keyword">bool</span></code>; Boost.YAP does
685              not check this.
686            </p></dd>
687<dt><span class="term"><a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a></span></dt>
688<dd><p>
689              An <code class="computeroutput"><span class="identifier">expr_ref</span></code> expression
690              is one that acts as a (possibly <code class="computeroutput"><span class="keyword">const</span></code>)
691              lvalue reference to another expression. It exists to prevent unnecessary
692              copies of expressions.
693            </p></dd>
694</dl>
695</div>
696</div>
697<div class="section">
698<div class="titlepage"><div><div><h3 class="title">
699<a name="boost_yap.manual.operators"></a><a class="link" href="manual.html#boost_yap.manual.operators" title="Operators">Operators</a>
700</h3></div></div></div>
701<p>
702        Let's see an expression template type with some operators:
703      </p>
704<p>
705</p>
706<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
707<span class="keyword">struct</span> <span class="identifier">lazy_vector_expr</span>
708<span class="special">{</span>
709    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
710
711    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
712
713    <span class="comment">// Note that this does not return an expression; it is greedily evaluated.</span>
714    <span class="keyword">auto</span> <span class="keyword">operator</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">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
715<span class="special">};</span>
716
717<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">)</span>
718<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">)</span>
719</pre>
720<p>
721      </p>
722<p>
723        Those macros are used to define operator overloads that return <a class="link" href="concepts.html#boost_yap.concepts.expression">Expressions</a>.
724        As shown here, that sort of operator can be mixed with normal, non-lazy ones
725        — the <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>
726        is a normal eager function.
727      </p>
728<p>
729        Use of the macros is not necessary (you can write your own operators that
730        return <a class="link" href="concepts.html#boost_yap.concepts.expression">Expressions</a> if
731        you like), but it is suitable 99% of the time.
732      </p>
733<p>
734        Making the operators easy to define like this allows you to define custom
735        expression templates that have only the operators defined that are appropriate
736        for your use case.
737      </p>
738<p>
739        Detailed documentation on all the available macros can be found later in
740        the <a class="link" href="manual.html#boost_yap.manual.operator_macros" title="Operator Macros">Operator Macros</a>
741        section.
742      </p>
743</div>
744<div class="section">
745<div class="titlepage"><div><div><h3 class="title">
746<a name="boost_yap.manual.transforming_expressions"></a><a class="link" href="manual.html#boost_yap.manual.transforming_expressions" title="Transforming Expressions">Transforming
747      Expressions</a>
748</h3></div></div></div>
749<p>
750        Transformations in Boost.YAP are done using the <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
751        function.
752      </p>
753<p>
754        Let's take another look at the example expression from the intro:
755      </p>
756<p>
757        <span class="inlinemediaobject"><img src="../yap/img/expr.png" alt="expr"></span>
758      </p>
759<p>
760        Consider a call to <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>,
761        operating on that expression:
762      </p>
763<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">xform</span><span class="special">);</span>
764</pre>
765<p>
766        Boost.YAP's <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> first looks at the top level
767        expression, which in this case is a <code class="computeroutput"><span class="special">+</span></code>
768        expression. If the transform object <code class="computeroutput"><span class="identifier">xform</span></code>
769        matches the <code class="computeroutput"><span class="special">+</span></code> expression, <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> is done; it just returns
770        <code class="computeroutput"><span class="identifier">xform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span></code>.
771        If <code class="computeroutput"><span class="identifier">xform</span></code> does not match the
772        <code class="computeroutput"><span class="special">+</span></code> expression, <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> transforms all its operands
773        (which for <code class="computeroutput"><span class="keyword">operator</span><span class="special">+()</span></code>
774        is just the left and right operands), and returns a new <code class="computeroutput"><span class="special">+</span></code>
775        expression with those transformed operands. What I mean by "match"
776        is covered in detail below.
777      </p>
778<p>
779        The overall effect of this is that <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
780        effectively copies an <code class="computeroutput"><span class="identifier">expr</span></code>
781        node that <span class="bold"><strong>does not</strong></span> match <code class="computeroutput"><span class="identifier">xform</span></code>,
782        and returns a transformed node for an <code class="computeroutput"><span class="identifier">expr</span></code>
783        node that <span class="bold"><strong>does</strong></span> match <code class="computeroutput"><span class="identifier">xform</span></code>.
784      </p>
785<p>
786        <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> can also take multiple transform
787        objects. If you call it with N transform objects, it will attempt to match
788        each of the N transforms to a given expression, one at a time and in their
789        given order. Only if no transform matches an expression does the copy-and-recurse
790        behavior kick in.
791      </p>
792<div class="note"><table border="0" summary="Note">
793<tr>
794<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
795<th align="left">Note</th>
796</tr>
797<tr><td align="left" valign="top"><p>
798          There's another form of <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>,
799          <code class="computeroutput"><a class="link" href="../boost/yap/transform_strict.html" title="Function template transform_strict">transform_strict()</a></code>. <code class="computeroutput"><a class="link" href="../boost/yap/transform_strict.html" title="Function template transform_strict">transform_strict()</a></code>
800          is identical to <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
801          except that it does not copy or recurse into an unmatched expression. Instead,
802          a failed match is a hard error. This is useful when you have written a
803          transform that you expect to completely transform an expression, and you
804          want the compiler to tell you if you've made a mistake.
805        </p></td></tr>
806</table></div>
807<p>
808        One common result of calling <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
809        is that you create a copy of <code class="computeroutput"><span class="identifier">expr</span></code>,
810        with a few matching nodes transformed. But this does not have to be the result
811        of calling <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>, because a Boost.YAP transformation
812        is free-form; it must return a value, but may do just about anything else.
813        It can transform an expression into anything — a new expression of
814        any kind, or even a non-expression value (effectively evaluating the expression).
815        As before, here is the <code class="computeroutput"><span class="identifier">get_arity</span></code>
816        transform from the <a class="link" href="manual.html#boost_yap.manual.examples.calc3" title="Calc3">Calc3</a>
817        example. It returns a value, not an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>:
818      </p>
819<p>
820</p>
821<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">get_arity</span>
822<span class="special">{</span>
823    <span class="comment">// Base case 1: Match a placeholder terminal, and return its arity as the</span>
824    <span class="comment">// result.</span>
825    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">&gt;</span>
826    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
827                                      <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;)</span>
828    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;;</span> <span class="special">}</span>
829
830    <span class="comment">// Base case 2: Match any other terminal.  Return 0; non-placeholders do</span>
831    <span class="comment">// not contribute to arity.</span>
832    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
833    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span> <span class="identifier">T</span> <span class="special">&amp;&amp;)</span>
834    <span class="special">{</span>
835        <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
836        <span class="keyword">return</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">;</span>
837    <span class="special">}</span>
838
839    <span class="comment">// Recursive case: Match any expression not covered above, and return the</span>
840    <span class="comment">// maximum of its children's arities.</span>
841    <span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Arg</span><span class="special">&gt;</span>
842    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">&gt;,</span> <span class="identifier">Arg</span> <span class="special">&amp;&amp;...</span> <span class="identifier">arg</span><span class="special">)</span>
843    <span class="special">{</span>
844        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">(</span>
845            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span>
846                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span>
847                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Arg</span><span class="special">&gt;(</span><span class="identifier">arg</span><span class="special">)),</span>
848                    <span class="identifier">get_arity</span><span class="special">{}</span>
849                <span class="special">)...</span>
850            <span class="special">)</span>
851        <span class="special">);</span>
852    <span class="special">}</span>
853<span class="special">};</span>
854</pre>
855<p>
856      </p>
857<p>
858        Also, note that in this case the transform is stateless, but you could also
859        give your transform objects data members containing contextual state:
860      </p>
861<p>
862</p>
863<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">take_nth</span>
864<span class="special">{</span>
865    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
866    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
867                     <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">vec</span><span class="special">)</span>
868    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">vec</span><span class="special">[</span><span class="identifier">n</span><span class="special">]);</span> <span class="special">}</span>
869
870    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">;</span>
871<span class="special">};</span>
872</pre>
873<p>
874      </p>
875<div class="tip"><table border="0" summary="Tip">
876<tr>
877<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
878<th align="left">Tip</th>
879</tr>
880<tr><td align="left" valign="top"><p>
881          Often when you create an expression, you will want to evaluate it in different
882          contexts, changing its evaluation — or even entire meaning —
883          in each context. <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>
884          is wrong for this task, since it only takes values for substitution into
885          placeholders. In these situations, you should instead use multiple transforms
886          that evaluate your expression in different ways.
887        </p></td></tr>
888</table></div>
889<h5>
890<a name="boost_yap.manual.transforming_expressions.h0"></a>
891        <span class="phrase"><a name="boost_yap.manual.transforming_expressions.when__functionname_alt__boost__yap__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special______phrase___code___functionname__recurses"></a></span><a class="link" href="manual.html#boost_yap.manual.transforming_expressions.when__functionname_alt__boost__yap__transform___code__phrase_role__identifier__transform__phrase__phrase_role__special______phrase___code___functionname__recurses">When
892        transform() Recurses</a>
893      </h5>
894<p>
895        As described above, <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
896        only recurses when it <span class="bold"><strong>does not</strong></span> find a match.
897        This means that if you want to transform a nonterminal, say an <code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span></code> expression we'll call <code class="computeroutput"><span class="identifier">C</span></code>, and <span class="bold"><strong>also</strong></span>
898        <code class="computeroutput"><span class="identifier">C</span></code>'s subexpressions, you must
899        explicitly call <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> yourself in your transform
900        that matches <code class="computeroutput"><span class="identifier">C</span></code>. You can see
901        this kind of explicit <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
902        call in the recursive case of <code class="computeroutput"><span class="identifier">get_arity</span></code>
903        in the example code above.
904      </p>
905<div class="note"><table border="0" summary="Note">
906<tr>
907<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
908<th align="left">Note</th>
909</tr>
910<tr><td align="left" valign="top"><p>
911          The code you write with Boost.YAP is likely going to be very generic, especially
912          when you're writing a transform. <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
913          requires an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
914          as its first parameter. In situations when you want to make sure that the
915          first parameter you pass to <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
916          is always a Boost.YAP expression, use the <code class="computeroutput"><a class="link" href="../boost/yap/as_exp_1_3_48_8_2_2_1_1_15.html" title="Function template as_expr">as_expr()</a></code>
917          function. This is commonly needed when writing a transform in which you
918          manually recurse by calling <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>
919          inside one of your transform overloads.
920        </p></td></tr>
921</table></div>
922<h5>
923<a name="boost_yap.manual.transforming_expressions.h1"></a>
924        <span class="phrase"><a name="boost_yap.manual.transforming_expressions.transform_matching"></a></span><a class="link" href="manual.html#boost_yap.manual.transforming_expressions.transform_matching">Transform
925        Matching</a>
926      </h5>
927<p>
928        In Boost.YAP a <a class="link" href="concepts.html#boost_yap.concepts.transform">Transform</a>
929        is a <a href="http://en.cppreference.com/w/cpp/concept/Callable" target="_top">Callable</a>
930        that has <span class="bold"><strong>zero or more</strong></span> overloads that model
931        the <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
932        or <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a> concepts.
933      </p>
934<p>
935        An <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
936        overload takes a single parameter whose type is the expression to be transformed.
937        Here's one from a transform object in the <a class="link" href="manual.html#boost_yap.manual.examples.future_group" title="Future Group">Future
938        Group</a> example:
939      </p>
940<p>
941</p>
942<pre class="programlisting"><span class="comment">// Transform left || right -&gt; transform(left).</span>
943<span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
944<span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span>
945    <span class="identifier">future_expr</span><span class="special">&lt;</span>
946        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">logical_or</span><span class="special">,</span>
947        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">&gt;</span>
948    <span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">or_expr</span>
949<span class="special">)</span> <span class="special">{</span>
950    <span class="comment">// Recursively transform the left side, and return the result.</span>
951    <span class="comment">// Without the recursion, we might return a terminal expression here</span>
952    <span class="comment">// insead of a tuple.</span>
953    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">left</span><span class="special">(</span><span class="identifier">or_expr</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
954<span class="special">}</span>
955</pre>
956<p>
957      </p>
958<p>
959        <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransforms</a>
960        are most useful when you want to transform a narrow set of expression types
961        (perhaps only one). In particular, you can distinguish between <code class="computeroutput"><span class="keyword">const</span></code> and non-<code class="computeroutput"><span class="keyword">const</span></code>,
962        reference and non-reference, etc., in the expression and its operands in
963        a way that you have less control over with the other kind of transform.
964      </p>
965<p>
966        A <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a> overload
967        takes a tag that indicates the <code class="computeroutput"><a class="link" href="../boost/yap/expr_kind.html" title="Type expr_kind">expr_kind</a></code> of the expression
968        to be transformed, and then (loosely) the value of each operand of the expression
969        to be transformed. This looseness prevents you from needing to write out
970        the full type of the matched expression. Here's one from the <a class="link" href="manual.html#boost_yap.manual.examples.pipable_algorithms" title="Pipable Algorithms">Pipable
971        Algorithms</a> example:
972      </p>
973<p>
974</p>
975<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">&gt;</span>
976<span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span>
977    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;,</span>
978    <span class="identifier">algorithm_t</span> <span class="identifier">a</span><span class="special">,</span>
979    <span class="identifier">Range</span> <span class="special">&amp;</span> <span class="identifier">r</span><span class="special">)</span>
980<span class="special">{</span>
981    <span class="keyword">return</span> <span class="identifier">call_algorithm</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">r</span><span class="special">);</span>
982<span class="special">}</span>
983</pre>
984<p>
985      </p>
986<p>
987        <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransforms</a> are
988        most useful when the transform needs to match an expression without regard
989        to whether its operands are <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a> expressions, or —
990        if they are terminals — whether they contain or refer to their values.
991        <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransforms</a> tend
992        to be far more concise.
993      </p>
994<h5>
995<a name="boost_yap.manual.transforming_expressions.h2"></a>
996        <span class="phrase"><a name="boost_yap.manual.transforming_expressions.a_more_rigorous_description_of_tagtransform_parameters"></a></span><a class="link" href="manual.html#boost_yap.manual.transforming_expressions.a_more_rigorous_description_of_tagtransform_parameters">A
997        More Rigorous Description of TagTransform Parameters</a>
998      </h5>
999<p>
1000        That "(loosely)" before probably bothered you, right? Me too. Each
1001        non-tag parameter is passed to a <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>
1002        by calling an operand accessor appropriate to <code class="computeroutput"><span class="identifier">expr</span></code>'s
1003        kind, and then calling a terminal-specific version of <code class="computeroutput"><a class="link" href="../boost/yap/value.html" title="Function template value">value()</a></code>
1004        (<code class="computeroutput"><span class="identifier">terminal_value</span><span class="special">()</span></code>)
1005        on the result. For example, consider a plus expression <code class="computeroutput"><span class="identifier">expr</span></code>.
1006        The <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a> on
1007        a transform object <code class="computeroutput"><span class="identifier">xform</span></code>
1008        would be called like this:
1009      </p>
1010<pre class="programlisting"><span class="identifier">xform</span><span class="special">(</span><span class="identifier">plus_tag</span><span class="special">,</span> <span class="identifier">terminal_value</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">terminal_value</span><span class="special">(</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)))</span>
1011</pre>
1012<p>
1013        The operand accessors (<code class="computeroutput"><a class="link" href="../boost/yap/left.html" title="Function template left">left()</a></code>
1014        and <code class="computeroutput"><a class="link" href="../boost/yap/right.html" title="Function template right">right()</a></code> in this example) all dereference
1015        <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a>
1016        expressions before operating on them, and <code class="computeroutput"><span class="identifier">terminal_value</span><span class="special">()</span></code> does the same.
1017      </p>
1018<p>
1019        <code class="computeroutput"><span class="identifier">terminal_value</span><span class="special">()</span></code>
1020        works much like <code class="computeroutput"><a class="link" href="../boost/yap/value.html" title="Function template value">value()</a></code>, except that it does not
1021        take the value of a <span class="bold"><strong>nonterminal</strong></span> unary expression;
1022        it just forwards a nonterminal through. It still takes values out of terminals
1023        and unwraps <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a>
1024        expressions, though.
1025      </p>
1026<p>
1027        The auto-unwrapping of terminals means that you can effectively ignore the
1028        presence of <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a>
1029        expressions when writing a <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>.
1030        You can also just deal with the values inside terminals, and not the terminals
1031        themselves. Also, you can match all terminal value qualifiers (<code class="computeroutput"><span class="keyword">const</span></code> or not, lvalue or rvalue) uniformly
1032        with a <code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span>
1033        <span class="special">&amp;</span></code> parameter. Finally, you can
1034        write <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>
1035        parameter types that can catch conversions; for instance, you can match any
1036        negation expression containing a terminal, <span class="bold"><strong>or a reference
1037        to one</strong></span>, containing a value convertible to <code class="computeroutput"><span class="keyword">double</span></code>
1038        like this:
1039      </p>
1040<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xform</span>
1041<span class="special">{</span>
1042    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">negate_tag</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span>
1043    <span class="special">{</span> <span class="keyword">return</span> <span class="comment">/* ... */</span><span class="special">;</span> <span class="special">}</span>
1044<span class="special">}</span>
1045</pre>
1046<p>
1047        That will match a negation of a terminal containing an <code class="computeroutput"><span class="keyword">unsigned</span>
1048        <span class="keyword">int</span></code>, <code class="computeroutput"><span class="keyword">unsigned</span>
1049        <span class="keyword">int</span> <span class="special">&amp;</span></code>,
1050        <code class="computeroutput"><span class="keyword">int</span> <span class="keyword">const</span>
1051        <span class="special">&amp;</span></code>, <code class="computeroutput"><span class="keyword">float</span>
1052        <span class="special">&amp;&amp;</span></code>, etc. It will also match
1053        a negation of a reference to such a terminal.
1054      </p>
1055<h5>
1056<a name="boost_yap.manual.transforming_expressions.h3"></a>
1057        <span class="phrase"><a name="boost_yap.manual.transforming_expressions.mixing_the_two_kinds_of_transforms"></a></span><a class="link" href="manual.html#boost_yap.manual.transforming_expressions.mixing_the_two_kinds_of_transforms">Mixing
1058        the Two Kinds of Transforms</a>
1059      </h5>
1060<p>
1061        You can have two overloads in your transform that match an expression, one
1062        an <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
1063        and one a <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>,
1064        and there will not be any ambiguity. The <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>
1065        is matched first, and the <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
1066        is matched only if the <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>
1067        did not. You don't have to worry about ambiguity, but save yourself some
1068        confusion and mix the two kinds of overloads as little as possible.
1069      </p>
1070<div class="note"><table border="0" summary="Note">
1071<tr>
1072<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
1073<th align="left">Note</th>
1074</tr>
1075<tr><td align="left" valign="top"><p>
1076          The above only applies when you have an <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
1077          and a <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>
1078          that match <span class="bold"><strong>the same kind of expression</strong></span>.
1079          Having unrelated <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransforms</a>
1080          and <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransforms</a>
1081          within the same transform object is often quite useful.
1082        </p></td></tr>
1083</table></div>
1084<h5>
1085<a name="boost_yap.manual.transforming_expressions.h4"></a>
1086        <span class="phrase"><a name="boost_yap.manual.transforming_expressions.multiple_transform_objects"></a></span><a class="link" href="manual.html#boost_yap.manual.transforming_expressions.multiple_transform_objects">Multiple
1087        Transform Objects</a>
1088      </h5>
1089<p>
1090        In the case that multiple transform objects are being used in <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code>, the above logic applies
1091        to each one independently before the next one is used. In other words, in
1092        the call <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span>
1093        <span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span></code>, <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> tries to match any <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a> from <code class="computeroutput"><span class="identifier">a</span></code> to an expression first, then any <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
1094        from <code class="computeroutput"><span class="identifier">a</span></code>, then any <a class="link" href="concepts.html#boost_yap.concepts.tagtransform">TagTransform</a>
1095        from <code class="computeroutput"><span class="identifier">b</span></code>, and finally any
1096        <a class="link" href="concepts.html#boost_yap.concepts.expressiontransform">ExpressionTransform</a>
1097        from <code class="computeroutput"><span class="identifier">b</span></code>. Only the first matching
1098        overload in this sequence is used; all overloads later in the sequence or
1099        in later transforms, whether they match or not, are simply ignored.
1100      </p>
1101<h5>
1102<a name="boost_yap.manual.transforming_expressions.h5"></a>
1103        <span class="phrase"><a name="boost_yap.manual.transforming_expressions.yap_supplied_transforms"></a></span><a class="link" href="manual.html#boost_yap.manual.transforming_expressions.yap_supplied_transforms">YAP-Supplied
1104        Transforms</a>
1105      </h5>
1106<p>
1107        Boost.YAP comes with a couple of functions that return ready-made transforms,
1108        <code class="computeroutput"><a class="link" href="../boost/yap/replacements.html" title="Function template replacements">replacements()</a></code> and <code class="computeroutput"><a class="link" href="../boost/yap/evaluation.html" title="Function template evaluation">evaluation()</a></code>.
1109      </p>
1110<p>
1111        The transforms returned by <code class="computeroutput"><a class="link" href="../boost/yap/replacements.html" title="Function template replacements">replacements()</a></code>
1112        replace only placeholder terminals. Placeholder <code class="computeroutput"><span class="identifier">I</span></code>
1113        is replaced by the <code class="computeroutput"><span class="identifier">I</span><span class="special">-</span><span class="number">1</span></code>-th argument passed to <code class="computeroutput"><a class="link" href="../boost/yap/replacements.html" title="Function template replacements">replacements()</a></code>.
1114        Placeholders are <code class="computeroutput"><span class="number">1</span></code>-based for
1115        consistency with other Boost and <code class="computeroutput"><span class="identifier">std</span></code>
1116        placeholders.
1117      </p>
1118<p>
1119        There are also a couple of specialty transform functions, <code class="computeroutput"><a class="link" href="../boost/yap/replace_placeholders.html" title="Function template replace_placeholders">replace_placeholders()</a></code>
1120        and <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>. These are convenience functions
1121        that just call <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> on an expression using
1122        <code class="computeroutput"><a class="link" href="../boost/yap/replacements.html" title="Function template replacements">replacements()</a></code> or <code class="computeroutput"><a class="link" href="../boost/yap/evaluation.html" title="Function template evaluation">evaluation()</a></code>
1123        as the transform, respectively.
1124      </p>
1125<p>
1126        The behavior of <code class="computeroutput"><a class="link" href="../boost/yap/evaluation.html" title="Function template evaluation">evaluation()</a></code>
1127        is covered in the next section, <a class="link" href="manual.html#boost_yap.manual.evaluating_expressions" title="Evaluating Expressions">Evaluating
1128        Expressions</a>.
1129      </p>
1130</div>
1131<div class="section">
1132<div class="titlepage"><div><div><h3 class="title">
1133<a name="boost_yap.manual.evaluating_expressions"></a><a class="link" href="manual.html#boost_yap.manual.evaluating_expressions" title="Evaluating Expressions">Evaluating Expressions</a>
1134</h3></div></div></div>
1135<p>
1136        Boost.YAP expressions are evaluated explicitly, by calling the <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code> function or calling <code class="computeroutput"><a class="link" href="../boost/yap/transform.html" title="Function template transform">transform()</a></code> using a transform object
1137        returned from <code class="computeroutput"><a class="link" href="../boost/yap/evaluation.html" title="Function template evaluation">evaluation()</a></code>. The former is a convenince
1138        function that does the latter.
1139      </p>
1140<p>
1141        <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code> simply removes all the Boost.YAP
1142        machinery from an expression and evaluates it exactly as it would have been
1143        if Boost.YAP were not used. This means that functions are called, operators
1144        evaluated, etc. all as normal. To illustrate this, take a look at the implementation
1145        of <code class="computeroutput"><span class="keyword">operator</span><span class="special">,()</span></code>
1146        used in <code class="computeroutput"><a class="link" href="../boost/yap/evaluate.html" title="Function template evaluate">evaluate()</a></code>:
1147      </p>
1148<p>
1149</p>
1150<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</span>
1151<span class="keyword">constexpr</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">comma</span><span class="special">&gt;,</span> <span class="identifier">T</span> <span class="special">&amp;&amp;</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">u</span><span class="special">)</span> <span class="keyword">const</span>
1152<span class="special">{</span>
1153    <span class="keyword">return</span> <span class="identifier">transform</span><span class="special">(</span>
1154               <span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">t</span><span class="special">)),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">),</span>
1155           <span class="identifier">transform</span><span class="special">(</span>
1156               <span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">U</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">u</span><span class="special">)),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
1157<span class="special">}</span>
1158</pre>
1159<p>
1160      </p>
1161<p>
1162        What this transformation does is transform the left and right expressions,
1163        and then use the built-in <code class="computeroutput"><span class="keyword">operator</span><span class="special">,()</span></code> on the result. The evaluation transformations
1164        for the other operators do the same thing — evaluate the operands,
1165        then return the result of applying the built-in operator to the operands.
1166      </p>
1167<p>
1168        Function calls are done in a similar way, except that the callable is also
1169        a subexpression that needs to be evaluated before being called:
1170      </p>
1171<p>
1172</p>
1173<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Callable</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span>
1174<span class="keyword">constexpr</span> <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="keyword">operator</span><span class="special">()(</span>
1175    <span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;,</span> <span class="identifier">Callable</span> <span class="special">&amp;&amp;</span> <span class="identifier">callable</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="keyword">const</span>
1176<span class="special">{</span>
1177    <span class="keyword">return</span> <span class="identifier">transform</span><span class="special">(</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">Callable</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">callable</span><span class="special">)),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)(</span>
1178        <span class="identifier">transform</span><span class="special">(</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">Args</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">args</span><span class="special">)),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)...</span>
1179    <span class="special">);</span>
1180<span class="special">}</span>
1181</pre>
1182<p>
1183      </p>
1184</div>
1185<div class="section">
1186<div class="titlepage"><div><div><h3 class="title">
1187<a name="boost_yap.manual.operator_macros"></a><a class="link" href="manual.html#boost_yap.manual.operator_macros" title="Operator Macros">Operator Macros</a>
1188</h3></div></div></div>
1189<p>
1190        If you got here without reading the <a class="link" href="manual.html#boost_yap.manual.operators" title="Operators">Operators</a>
1191        section, go read that first. Here are the operator macros and their uses:
1192      </p>
1193<div class="table">
1194<a name="boost_yap.manual.operator_macros.unary_and_binary_operator_defining_macros"></a><p class="title"><b>Table 47.1. Unary and Binary Operator-Defining Macros</b></p>
1195<div class="table-contents"><table class="table" summary="Unary and Binary Operator-Defining Macros">
1196<colgroup>
1197<col>
1198<col>
1199<col>
1200<col>
1201<col>
1202</colgroup>
1203<thead><tr>
1204<th>
1205                <p>
1206                  Macro
1207                </p>
1208              </th>
1209<th>
1210                <p>
1211                  Use
1212                </p>
1213              </th>
1214<th>
1215                <p>
1216                  First/Left Operand Type
1217                </p>
1218              </th>
1219<th>
1220                <p>
1221                  Right Operand Type
1222                </p>
1223              </th>
1224<th>
1225                <p>
1226                  Notes
1227                </p>
1228              </th>
1229</tr></thead>
1230<tbody>
1231<tr>
1232<td>
1233                <p>
1234                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_1.html" title="Macro BOOST_YAP_USER_UNARY_OPERATOR">BOOST_YAP_USER_UNARY_OPERATOR</a></code>
1235                </p>
1236              </td>
1237<td>
1238                <p>
1239                  Unary operators.
1240                </p>
1241              </td>
1242<td>
1243                <p>
1244                  An <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1245                  instantiated from <a class="link" href="concepts.html#boost_yap.concepts.expressiontemplate">ExpressionTemplate</a>
1246                  macro parameter <code class="computeroutput"><span class="identifier">expr_template</span></code>.
1247                </p>
1248              </td>
1249<td>
1250                <p>
1251                  --
1252                </p>
1253              </td>
1254<td>
1255              </td>
1256</tr>
1257<tr>
1258<td>
1259                <p>
1260                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_2.html" title="Macro BOOST_YAP_USER_BINARY_OPERATOR">BOOST_YAP_USER_BINARY_OPERATOR</a></code>
1261                </p>
1262              </td>
1263<td>
1264                <p>
1265                  Binary operators.
1266                </p>
1267              </td>
1268<td>
1269                <p>
1270                  Any type.
1271                </p>
1272              </td>
1273<td>
1274                <p>
1275                  Any type.
1276                </p>
1277              </td>
1278<td>
1279                <p>
1280                  At least one parameter must be an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1281                  instantiated from <a class="link" href="concepts.html#boost_yap.concepts.expressiontemplate">ExpressionTemplate</a>
1282                  macro parameter <code class="computeroutput"><span class="identifier">expr_template</span></code>.
1283                </p>
1284              </td>
1285</tr>
1286<tr>
1287<td>
1288                <p>
1289                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_9.html" title="Macro BOOST_YAP_USER_UDT_UNARY_OPERATOR">BOOST_YAP_USER_UDT_UNARY_OPERATOR</a></code>
1290                </p>
1291              </td>
1292<td>
1293                <p>
1294                  Free operators defined over non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1295                  types constrained by a type trait (e.g. all <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;&gt;</span></code>s).
1296                </p>
1297              </td>
1298<td>
1299                <p>
1300                  Any non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1301                  that satisfies the given type trait.
1302                </p>
1303              </td>
1304<td>
1305                <p>
1306                  --
1307                </p>
1308              </td>
1309<td>
1310              </td>
1311</tr>
1312<tr>
1313<td>
1314                <p>
1315                  <code class="computeroutput"><a class="link" href="../BOOST_YAP__1_3_48_8_2_7_10.html" title="Macro BOOST_YAP_USER_UDT_UDT_BINARY_OPERATOR">BOOST_YAP_USER_UDT_UDT_BINARY_OPERATOR</a></code>
1316                </p>
1317              </td>
1318<td>
1319                <p>
1320                  Free operators defined over non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1321                  types constrained by a pair of type traits (e.g. a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;&gt;</span></code>
1322                  on the left, and a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;&gt;</span></code> on the right). Useful for
1323                  type-asymmetric operators.
1324                </p>
1325              </td>
1326<td>
1327                <p>
1328                  Any non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1329                  that satisfies the left-hand type trait.
1330                </p>
1331              </td>
1332<td>
1333                <p>
1334                  Any non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1335                  that satisfies the right-hand type trait.
1336                </p>
1337              </td>
1338<td>
1339              </td>
1340</tr>
1341<tr>
1342<td>
1343                <p>
1344                  <code class="computeroutput"><a class="link" href="../BOOST_YAP__1_3_48_8_2_7_11.html" title="Macro BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</a></code>
1345                </p>
1346              </td>
1347<td>
1348                <p>
1349                  Free operators defined over pairs of non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1350                  types, one constrained by a type trait and one not (e.g. a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;&gt;</span></code>
1351                  on either side, and anything on the other).
1352                </p>
1353              </td>
1354<td>
1355                <p>
1356                  Any non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>.
1357                </p>
1358              </td>
1359<td>
1360                <p>
1361                  --
1362                </p>
1363              </td>
1364<td>
1365                <p>
1366                  At least one parameter must satisfy the given type trait.
1367                </p>
1368              </td>
1369</tr>
1370</tbody>
1371</table></div>
1372</div>
1373<br class="table-break"><p>
1374        Some operators may only be defined as member functions, and so are not covered
1375        by general-purpose the unary and binary operator macros above:
1376      </p>
1377<div class="table">
1378<a name="boost_yap.manual.operator_macros.the_member_only_operator_macros"></a><p class="title"><b>Table 47.2. The Member-Only Operator Macros</b></p>
1379<div class="table-contents"><table class="table" summary="The Member-Only Operator Macros">
1380<colgroup>
1381<col>
1382<col>
1383<col>
1384<col>
1385</colgroup>
1386<thead><tr>
1387<th>
1388                <p>
1389                  Macro
1390                </p>
1391              </th>
1392<th>
1393                <p>
1394                  Use
1395                </p>
1396              </th>
1397<th>
1398                <p>
1399                  Operands
1400                </p>
1401              </th>
1402<th>
1403                <p>
1404                  Notes
1405                </p>
1406              </th>
1407</tr></thead>
1408<tbody>
1409<tr>
1410<td>
1411                <p>
1412                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_3.html" title="Macro BOOST_YAP_USER_ASSIGN_OPERATOR">BOOST_YAP_USER_ASSIGN_OPERATOR</a></code>
1413                </p>
1414              </td>
1415<td>
1416                <p>
1417                  Assignment operator.
1418                </p>
1419              </td>
1420<td>
1421                <p>
1422                  Any type except <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span></code>.
1423                </p>
1424              </td>
1425<td>
1426                <p>
1427                  Does not conflict with the assignment or move assignment operators.
1428                </p>
1429              </td>
1430</tr>
1431<tr>
1432<td>
1433                <p>
1434                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_4.html" title="Macro BOOST_YAP_USER_SUBSCRIPT_OPERATOR">BOOST_YAP_USER_SUBSCRIPT_OPERATOR</a></code>
1435                </p>
1436              </td>
1437<td>
1438                <p>
1439                  Subscript operator.
1440                </p>
1441              </td>
1442<td>
1443                <p>
1444                  Any type.
1445                </p>
1446              </td>
1447<td>
1448              </td>
1449</tr>
1450<tr>
1451<td>
1452                <p>
1453                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_5.html" title="Macro BOOST_YAP_USER_CALL_OPERATOR">BOOST_YAP_USER_CALL_OPERATOR</a></code>
1454                </p>
1455              </td>
1456<td>
1457                <p>
1458                  Call operator taking any number of parameters.
1459                </p>
1460              </td>
1461<td>
1462                <p>
1463                  Any type.
1464                </p>
1465              </td>
1466<td>
1467              </td>
1468</tr>
1469<tr>
1470<td>
1471                <p>
1472                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_6.html" title="Macro BOOST_YAP_USER_CALL_OPERATOR_N">BOOST_YAP_USER_CALL_OPERATOR_N</a></code>
1473                </p>
1474              </td>
1475<td>
1476                <p>
1477                  Call operator taking exactly N parameters.
1478                </p>
1479              </td>
1480<td>
1481                <p>
1482                  Any type.
1483                </p>
1484              </td>
1485<td>
1486              </td>
1487</tr>
1488</tbody>
1489</table></div>
1490</div>
1491<br class="table-break"><div class="table">
1492<a name="boost_yap.manual.operator_macros.if_else_psuedo_operator_macros"></a><p class="title"><b>Table 47.3. if_else Psuedo-Operator Macros</b></p>
1493<div class="table-contents"><table class="table" summary="if_else Psuedo-Operator Macros">
1494<colgroup>
1495<col>
1496<col>
1497<col>
1498<col>
1499</colgroup>
1500<thead><tr>
1501<th>
1502                <p>
1503                  Macro
1504                </p>
1505              </th>
1506<th>
1507                <p>
1508                  Use
1509                </p>
1510              </th>
1511<th>
1512                <p>
1513                  Operands
1514                </p>
1515              </th>
1516<th>
1517                <p>
1518                  Notes
1519                </p>
1520              </th>
1521</tr></thead>
1522<tbody>
1523<tr>
1524<td>
1525                <p>
1526                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_7.html" title="Macro BOOST_YAP_USER_EXPR_IF_ELSE">BOOST_YAP_USER_EXPR_IF_ELSE</a></code>
1527                </p>
1528              </td>
1529<td>
1530                <p>
1531                  Free <code class="computeroutput"><span class="identifier">if_else</span><span class="special">()</span></code>
1532                  function that requires at least one parameter to be an expression.
1533                </p>
1534              </td>
1535<td>
1536                <p>
1537                  Any type.
1538                </p>
1539              </td>
1540<td>
1541                <p>
1542                  At least one parameter must be an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>.
1543                </p>
1544              </td>
1545</tr>
1546<tr>
1547<td>
1548                <p>
1549                  <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_8.html" title="Macro BOOST_YAP_USER_UDT_ANY_IF_ELSE">BOOST_YAP_USER_UDT_ANY_IF_ELSE</a></code>
1550                </p>
1551              </td>
1552<td>
1553                <p>
1554                  Free <code class="computeroutput"><span class="identifier">if_else</span><span class="special">()</span></code>
1555                  function for non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1556                  types that requires at least one parameter to satisfy the given
1557                  type trait.
1558                </p>
1559              </td>
1560<td>
1561                <p>
1562                  Any non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>.
1563                </p>
1564              </td>
1565<td>
1566                <p>
1567                  At least one parameter must satisfy the given type trait.
1568                </p>
1569              </td>
1570</tr>
1571</tbody>
1572</table></div>
1573</div>
1574<br class="table-break"><div class="note"><table border="0" summary="Note">
1575<tr>
1576<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
1577<th align="left">Note</th>
1578</tr>
1579<tr><td align="left" valign="top"><p>
1580          Operands are handled in a uniform way across all functions defined by all
1581          the macros listed here. See <a class="link" href="manual.html#boost_yap.manual.how_expression_operands_are_treated" title="How Expression Operands Are Treated">How
1582          Expression Operands Are Treated</a> for details.
1583        </p></td></tr>
1584</table></div>
1585</div>
1586<div class="section">
1587<div class="titlepage"><div><div><h3 class="title">
1588<a name="boost_yap.manual.how_expression_operands_are_treated"></a><a class="link" href="manual.html#boost_yap.manual.how_expression_operands_are_treated" title="How Expression Operands Are Treated">How
1589      Expression Operands Are Treated</a>
1590</h3></div></div></div>
1591<p>
1592        For any <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code> operator overload, or
1593        any function defined using one of the function definition macros, operands
1594        are treated in a uniform way.
1595      </p>
1596<p>
1597        The guiding design principle here is that an expression built using Boost.YAP
1598        should match the semantics of a builtin C++ expression as closely as possible.
1599        This implies that an rvalue be treated as if it were a temporary (as it may
1600        in fact have initially been) throughout the building and transformation of
1601        an expression, and that an lvalue should retain its connection to the underlying
1602        named entity to which it refers.
1603      </p>
1604<p>
1605        For example, if you see
1606      </p>
1607<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">+</span> <span class="number">1</span><span class="special">;</span>
1608</pre>
1609<p>
1610        you should expect that <code class="computeroutput"><span class="identifier">a</span></code>
1611        will be an lvalue reference to some object of type <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span></code>,
1612        regardless of whether <code class="computeroutput"><span class="identifier">a</span></code> is
1613        a Boost.YAP <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1614        or a builtin type. Similarly, you should expect the <code class="computeroutput"><span class="number">1</span></code>
1615        to be an rvalue, whether wrapped in a terminal or not.
1616      </p>
1617<p>
1618        Let's take a quick look at <code class="computeroutput"><a class="link" href="../boost/yap/make_t_1_3_48_8_2_2_1_1_14.html" title="Function template make_terminal">make_terminal()</a></code>.
1619        If you call it with a <code class="computeroutput"><span class="identifier">T</span></code> rvalue,
1620        the terminal's value type is a <code class="computeroutput"><span class="identifier">T</span></code>,
1621        and the rvalue gets moved into it. If you call it with a <code class="computeroutput"><span class="identifier">T</span>
1622        <span class="special">[</span><span class="keyword">const</span><span class="special">]</span></code> lvalue, the value type is <code class="computeroutput"><span class="identifier">T</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]</span> <span class="special">&amp;</span></code>, and
1623        the reference refers to the lvalue (read <code class="computeroutput"><span class="special">[</span><span class="keyword">const</span><span class="special">]</span></code> as
1624        "possibly <code class="computeroutput"><span class="keyword">const</span></code>-qualified").
1625        This is important because you might write through the terminal later in an
1626        assignment operation. You don't want to lose the ability to do this, or be
1627        forced to write some Baroque pile of code to do so — it should be
1628        natural and easy.
1629      </p>
1630<p>
1631        And it is:
1632      </p>
1633<p>
1634</p>
1635<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
1636<span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">=</span> <span class="number">42</span><span class="special">;</span>
1637<span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
1638<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// Prints 42.</span>
1639</pre>
1640<p>
1641      </p>
1642<p>
1643        Now, there is a wrinkle. Boost.YAP's lazy expressions can be built piecemeal:
1644      </p>
1645<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">subexpr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</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>
1646<span class="comment">// This is fine, and acts more-or-less as if you wrote "1 / (1 + 2)".</span>
1647<span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="number">1</span> <span class="special">/</span> <span class="identifier">subexpr</span><span class="special">;</span>
1648</pre>
1649<p>
1650        whereas C++'s eager builtin expressions cannot:
1651      </p>
1652<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">subexpr</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">// Same as "int subexpr = 3;".  Hm.</span>
1653<span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="number">1</span> <span class="special">/</span> <span class="identifier">subexpr</span><span class="special">;</span> <span class="comment">// Same as "int expr = 0;" Arg.</span>
1654</pre>
1655<p>
1656        Ok, so since you can build these lazy Boost.YAP expressions up from subexpressions,
1657        how do we treat the subexpressions? We treat them in exactly the same way
1658        as <code class="computeroutput"><a class="link" href="../boost/yap/make_t_1_3_48_8_2_2_1_1_14.html" title="Function template make_terminal">make_terminal()</a></code> treats its parameter. Rvalues
1659        are moved in, and lvalues are captured by (possibly <code class="computeroutput"><span class="keyword">const</span></code>)
1660        reference.
1661      </p>
1662<div class="note"><table border="0" summary="Note">
1663<tr>
1664<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
1665<th align="left">Note</th>
1666</tr>
1667<tr><td align="left" valign="top"><p>
1668          If you want to subvert the capture-by-reference semantics of using subexpressions,
1669          just <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">()</span></code>
1670          them. That will force a move — or copy of values for which move
1671          is not defined.
1672        </p></td></tr>
1673</table></div>
1674<p>
1675        The capture-by-reference behavior is implemented via a special <code class="computeroutput"><a class="link" href="../boost/yap/expr_kind.html" title="Type expr_kind">expr_kind</a></code>,
1676        <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a>.
1677        An <code class="computeroutput"><span class="identifier">expr_ref</span></code> expression has
1678        a single data element: a (possibly <code class="computeroutput"><span class="keyword">const</span></code>
1679        (Can I stop saying that every time? You get it, right? Ok, good.)) reference
1680        to an expression. This additional level of indirection causes some complications
1681        at times, as you can see in the examples. Fortunately, the complications
1682        are not overly cumbersome.
1683      </p>
1684<p>
1685        So, given the rules above, here is a comprehensive breakdown of what happens
1686        when an operand is passed to a Boost.YAP operator. In this table, <code class="computeroutput"><span class="identifier">expr_tmpl</span></code> is an <a class="link" href="concepts.html#boost_yap.concepts.expressiontemplate">ExpressionTemplate</a>,
1687        and <code class="computeroutput"><span class="identifier">T</span></code> is a non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1688        type. <code class="computeroutput"><span class="identifier">E</span></code> refers to any non-<code class="computeroutput"><span class="identifier">expr_ref</span></code> <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>.
1689        Boost.YAP does a partial decay on non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1690        operands, in which <code class="computeroutput"><span class="identifier">cv</span></code> and
1691        reference qualifiers are left unchanged, but arrays are decayed to pointers
1692        and functions are decayed to function pointers. <code class="computeroutput"><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>
1693        indicates such a partial decay of <code class="computeroutput"><span class="identifier">T</span></code>.
1694      </p>
1695<div class="table">
1696<a name="boost_yap.manual.how_expression_operands_are_treated.operand_handling"></a><p class="title"><b>Table 47.4. Operand Handling</b></p>
1697<div class="table-contents"><table class="table" summary="Operand Handling">
1698<colgroup>
1699<col>
1700<col>
1701<col>
1702</colgroup>
1703<thead><tr>
1704<th>
1705                <p>
1706                  Operand
1707                </p>
1708              </th>
1709<th>
1710                <p>
1711                  Captured As
1712                </p>
1713              </th>
1714<th>
1715                <p>
1716                  Notes
1717                </p>
1718              </th>
1719</tr></thead>
1720<tbody>
1721<tr>
1722<td>
1723                <p>
1724                  <code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span>
1725                  <span class="special">&amp;</span></code>
1726                </p>
1727              </td>
1728<td>
1729                <p>
1730                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
1731                  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)&gt;&gt;</span></code>
1732                </p>
1733              </td>
1734<td>
1735              </td>
1736</tr>
1737<tr>
1738<td>
1739                <p>
1740                  <code class="computeroutput"><span class="identifier">T</span> <span class="special">&amp;</span></code>
1741                </p>
1742              </td>
1743<td>
1744                <p>
1745                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
1746                  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)&gt;&gt;</span></code>
1747                </p>
1748              </td>
1749<td>
1750              </td>
1751</tr>
1752<tr>
1753<td>
1754                <p>
1755                  <code class="computeroutput"><span class="identifier">T</span> <span class="special">&amp;&amp;</span></code>
1756                </p>
1757              </td>
1758<td>
1759                <p>
1760                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
1761                  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)&gt;&gt;</span></code>
1762                </p>
1763              </td>
1764<td>
1765                <p>
1766                  Operand moved.
1767                </p>
1768              </td>
1769</tr>
1770<tr>
1771<td>
1772                <p>
1773                  <code class="computeroutput"><span class="identifier">E</span> <span class="keyword">const</span>
1774                  <span class="special">&amp;</span></code>
1775                </p>
1776              </td>
1777<td>
1778                <p>
1779                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1780                  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">E</span> <span class="keyword">const</span>
1781                  <span class="special">&amp;&gt;&gt;</span></code>
1782                </p>
1783              </td>
1784<td>
1785              </td>
1786</tr>
1787<tr>
1788<td>
1789                <p>
1790                  <code class="computeroutput"><span class="identifier">E</span> <span class="special">&amp;</span></code>
1791                </p>
1792              </td>
1793<td>
1794                <p>
1795                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1796                  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">E</span> <span class="special">&amp;&gt;&gt;</span></code>
1797                </p>
1798              </td>
1799<td>
1800              </td>
1801</tr>
1802<tr>
1803<td>
1804                <p>
1805                  <code class="computeroutput"><span class="identifier">E</span> <span class="special">&amp;&amp;</span></code>
1806                </p>
1807              </td>
1808<td>
1809                <p>
1810                  <code class="computeroutput"><span class="identifier">E</span></code>
1811                </p>
1812              </td>
1813<td>
1814                <p>
1815                  Operand moved.
1816                </p>
1817              </td>
1818</tr>
1819<tr>
1820<td>
1821                <p>
1822                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1823                  <span class="special">...&gt;</span> <span class="keyword">const</span>
1824                  <span class="special">&amp;</span></code>
1825                </p>
1826              </td>
1827<td>
1828                <p>
1829                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1830                  <span class="special">...&gt;</span></code>
1831                </p>
1832              </td>
1833<td>
1834              </td>
1835</tr>
1836<tr>
1837<td>
1838                <p>
1839                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1840                  <span class="special">...&gt;</span> <span class="special">&amp;</span></code>
1841                </p>
1842              </td>
1843<td>
1844                <p>
1845                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1846                  <span class="special">...&gt;</span></code>
1847                </p>
1848              </td>
1849<td>
1850              </td>
1851</tr>
1852<tr>
1853<td>
1854                <p>
1855                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1856                  <span class="special">...&gt;</span> <span class="special">&amp;&amp;</span></code>
1857                </p>
1858              </td>
1859<td>
1860                <p>
1861                  <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special">&lt;</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span>
1862                  <span class="special">...&gt;</span></code>
1863                </p>
1864              </td>
1865<td>
1866                <p>
1867                  Operand moved.
1868                </p>
1869              </td>
1870</tr>
1871</tbody>
1872</table></div>
1873</div>
1874<br class="table-break"><p>
1875        The partial decay of non-<a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>
1876        operands is another example of how Boost.YAP attempts to create expression
1877        trees that are as semantically close to builtin expressions as possible.
1878      </p>
1879</div>
1880<div class="section">
1881<div class="titlepage"><div><div><h3 class="title">
1882<a name="boost_yap.manual.printing"></a><a class="link" href="manual.html#boost_yap.manual.printing" title="Printing">Printing</a>
1883</h3></div></div></div>
1884<p>
1885        Boost.YAP has a convenient <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code>
1886        function, that prints an expression tree to a stream. It is not intended
1887        for production work (for instance, it has no formatting options), but it
1888        is excellent for debugging and instrumentation.
1889      </p>
1890<p>
1891        Since it is only a debugging aid, <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code>
1892        is found in a separate header not included when you include Boost.YAP with
1893      </p>
1894<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1895</pre>
1896<p>
1897        You must include <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">print</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
1898        explicitly.
1899      </p>
1900<p>
1901        <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code> handles several patterns
1902        of expression specially, to allow a concise representation of a given expression
1903        tree. For example, given this definition:
1904      </p>
1905<p>
1906</p>
1907<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">thing</span> <span class="special">{};</span>
1908</pre>
1909<p>
1910      </p>
1911<p>
1912        and this expression:
1913      </p>
1914<p>
1915</p>
1916<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
1917
1918<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">const_lvalue_terminal_containing_rvalue</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="string">"lvalue terminal"</span><span class="special">);</span>
1919
1920<span class="keyword">double</span> <span class="keyword">const</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.0</span><span class="special">;</span>
1921<span class="keyword">auto</span> <span class="identifier">rvalue_terminal_containing_lvalue</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">d</span><span class="special">);</span>
1922
1923<span class="keyword">auto</span> <span class="identifier">thing_terminal</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">thing</span><span class="special">{});</span>
1924
1925<span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span>
1926    <span class="number">4</span><span class="identifier">_p</span> <span class="special">+</span>
1927    <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">rvalue_terminal_containing_lvalue</span><span class="special">)</span> <span class="special">*</span> <span class="identifier">thing_terminal</span> <span class="special">-</span>
1928    <span class="identifier">const_lvalue_terminal_containing_rvalue</span><span class="special">;</span>
1929</pre>
1930<p>
1931      </p>
1932<p>
1933        <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code> produces this output:
1934      </p>
1935<pre class="programlisting">expr&lt;-&gt;
1936    expr&lt;+&gt;
1937        term&lt;boost::yap::placeholder&lt;4ll&gt;&gt;[=4]
1938        expr&lt;*&gt;
1939            term&lt;double &amp;&gt;[=1]
1940            term&lt;thing&gt;[=&lt;&lt;unprintable-value&gt;&gt;] &amp;
1941    term&lt;char const*&gt;[=lvalue terminal] const &amp;
1942</pre>
1943<p>
1944        As you can see, <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code> shows one node per line,
1945        and represents the tree structure with indentation. It abbreviates non-terminal
1946        nodes in the tree <code class="computeroutput"><span class="identifier">expr</span><span class="special">&lt;</span><span class="identifier">op</span><span class="special">&gt;</span></code>,
1947        where <code class="computeroutput"><span class="identifier">op</span></code> is an operator symbol.
1948        Terminal nodes are abbreviated <code class="computeroutput"><span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>,
1949        where <code class="computeroutput"><span class="identifier">T</span></code> is the type of value
1950        contained in the terminal; this may be a reference type or a value.
1951      </p>
1952<p>
1953        A <code class="computeroutput"><span class="identifier">term</span></code> node may not be a
1954        terminal node at all, but an <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a> expression containing a
1955        terminal. Such a <a class="link" href="../boost/yap/expr_kind.html#boost.yap.expr_kind.expr_ref"><code class="computeroutput"><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span></code></a> node has a <code class="computeroutput"><span class="special">&amp;</span></code> or <code class="computeroutput"><span class="keyword">const</span>
1956        <span class="special">&amp;</span></code> suffix, to indicate that it
1957        is a mutable or <code class="computeroutput"><span class="keyword">const</span></code> reference,
1958        respectively.
1959      </p>
1960<p>
1961        Each <code class="computeroutput"><span class="identifier">term</span></code> node has a bracketed
1962        value near the end. The format is <code class="computeroutput"><span class="special">[=</span><span class="identifier">X</span><span class="special">]</span></code> where
1963        <code class="computeroutput"><span class="identifier">X</span></code> is the value the terminal
1964        contains. If the terminal contains a value for which no <code class="computeroutput"><span class="keyword">operator</span><span class="special">&lt;&lt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;,</span> <span class="special">...)</span></code>
1965        overload exists (such as the <code class="computeroutput"><span class="identifier">thing</span></code>
1966        type above), <code class="computeroutput"><span class="identifier">X</span></code> will be <code class="computeroutput"><span class="special">&lt;&lt;</span><span class="identifier">unprintable</span><span class="special">-</span><span class="identifier">value</span><span class="special">&gt;&gt;</span></code>.
1967      </p>
1968</div>
1969<div class="section">
1970<div class="titlepage"><div><div><h3 class="title">
1971<a name="boost_yap.manual.examples"></a><a class="link" href="manual.html#boost_yap.manual.examples" title="Examples">Examples</a>
1972</h3></div></div></div>
1973<div class="toc"><dl class="toc">
1974<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.hello_world">Hello World</a></span></dt>
1975<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.hello_world_redux">Hello
1976        World Redux</a></span></dt>
1977<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.minimal">Minimal</a></span></dt>
1978<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.calc1">Calc1</a></span></dt>
1979<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.calc2">Calc2</a></span></dt>
1980<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.calc3">Calc3</a></span></dt>
1981<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.lazy_vector">Lazy Vector</a></span></dt>
1982<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.self_evaluating_expressions">Self-Evaluating
1983        Expressions</a></span></dt>
1984<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.tarray">TArray</a></span></dt>
1985<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.vec3">Vec3</a></span></dt>
1986<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.vector">Vector</a></span></dt>
1987<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.mixed">Mixed</a></span></dt>
1988<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.map_assign">Map Assign</a></span></dt>
1989<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.future_group">Future Group</a></span></dt>
1990<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.autodiff">Autodiff</a></span></dt>
1991<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.transforming_terminals_only">Transforming
1992        Terminals Only</a></span></dt>
1993<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.pipable_algorithms">Pipable
1994        Algorithms</a></span></dt>
1995<dt><span class="section"><a href="manual.html#boost_yap.manual.examples.boost_phoenix_style__let___">Boost.Phoenix-style
1996        <code class="computeroutput"><span class="identifier">let</span><span class="special">()</span></code></a></span></dt>
1997</dl></div>
1998<p>
1999        Most of these examples are patterned after the examples from Boost.Proto.
2000        In part, this was done to underscore where Boost.YAP can do what Proto can,
2001        and where it cannot.
2002      </p>
2003<p>
2004        Where possible, a Proto-derived example uses syntax in <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code> identical to that in the original Proto
2005        example.
2006      </p>
2007<p>
2008        If you don't know anything about Proto, don't worry. The examples are useful
2009        on their own.
2010      </p>
2011<div class="section">
2012<div class="titlepage"><div><div><h4 class="title">
2013<a name="boost_yap.manual.examples.hello_world"></a><a class="link" href="manual.html#boost_yap.manual.examples.hello_world" title="Hello World">Hello World</a>
2014</h4></div></div></div>
2015<p>
2016          Remember how I mentioned earlier that Boost.YAP does things in a completely
2017          lazy way? Boost.YAP doesn't ever evaluate your expression eagerly. Eager
2018          evaluation can be done, but it's a bit of code.
2019        </p>
2020<p>
2021</p>
2022<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2023
2024<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2025
2026
2027<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2028<span class="special">{</span>
2029    <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</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">&lt;&lt;</span> <span class="string">"Hello"</span> <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="string">" world!\n"</span><span class="special">);</span>
2030
2031    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2032<span class="special">}</span>
2033</pre>
2034<p>
2035        </p>
2036</div>
2037<div class="section">
2038<div class="titlepage"><div><div><h4 class="title">
2039<a name="boost_yap.manual.examples.hello_world_redux"></a><a class="link" href="manual.html#boost_yap.manual.examples.hello_world_redux" title="Hello World Redux">Hello
2040        World Redux</a>
2041</h4></div></div></div>
2042<p>
2043          That's better! Sort of.... We created a custom expression template with
2044          an eager stream operator. This gives us eager evaluation, but gives away
2045          all the lazy AST building-then-evaluating that we're using expression templates
2046          for in the first place. In this simple example, we don't really need it.
2047        </p>
2048<p>
2049</p>
2050<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2051
2052<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2053
2054
2055<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2056<span class="keyword">struct</span> <span class="identifier">stream_expr</span>
2057<span class="special">{</span>
2058    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
2059
2060    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
2061
2062    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
2063    <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">T</span> <span class="special">&amp;&amp;</span> <span class="identifier">x</span><span class="special">)</span>
2064    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">T</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
2065<span class="special">};</span>
2066
2067
2068<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2069<span class="special">{</span>
2070    <span class="keyword">auto</span> <span class="identifier">cout</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">stream_expr</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
2071    <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Hello"</span> <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="string">" world!\n"</span><span class="special">;</span>
2072
2073    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2074<span class="special">}</span>
2075</pre>
2076<p>
2077        </p>
2078</div>
2079<div class="section">
2080<div class="titlepage"><div><div><h4 class="title">
2081<a name="boost_yap.manual.examples.minimal"></a><a class="link" href="manual.html#boost_yap.manual.examples.minimal" title="Minimal">Minimal</a>
2082</h4></div></div></div>
2083<p>
2084          <code class="computeroutput"><span class="identifier">minimal_expr</span></code> below models
2085          <a class="link" href="concepts.html#boost_yap.concepts.expressiontemplate">ExpressionTemplate</a>;
2086          since it has no operators, an expression must be built manually.
2087        </p>
2088<p>
2089          First, the template itself:
2090        </p>
2091<p>
2092</p>
2093<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2094<span class="keyword">struct</span> <span class="identifier">minimal_expr</span>
2095<span class="special">{</span>
2096    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
2097
2098    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
2099<span class="special">};</span>
2100</pre>
2101<p>
2102        </p>
2103<p>
2104          This can be used to make a <code class="computeroutput"><span class="identifier">minimal_expr</span></code>
2105          plus expression:
2106        </p>
2107<p>
2108</p>
2109<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">left</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="number">1</span><span class="special">);</span>
2110<span class="keyword">auto</span> <span class="identifier">right</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="number">41</span><span class="special">);</span>
2111
2112<span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_expression</span><span class="special">&lt;</span>
2113    <span class="identifier">minimal_expr</span><span class="special">,</span>
2114    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span>
2115<span class="special">&gt;(</span><span class="identifier">left</span><span class="special">,</span> <span class="identifier">right</span><span class="special">);</span>
2116</pre>
2117<p>
2118        </p>
2119<p>
2120          You can evaluate, transform, or otherwise operate on <code class="computeroutput"><span class="identifier">minimal_expr</span></code>
2121          expressions using the functions in Boost.YAP that accept an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>:
2122        </p>
2123<p>
2124</p>
2125<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
2126
2127<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span> <span class="comment">// prints "42"</span>
2128</pre>
2129<p>
2130        </p>
2131<div class="note"><table border="0" summary="Note">
2132<tr>
2133<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
2134<th align="left">Note</th>
2135</tr>
2136<tr><td align="left" valign="top"><p>
2137            Don't use Boost.YAP this way. Use the operator macros instead. This is
2138            an example contrived only to show you the minimum requirements on a Boost.YAP-compatible
2139            template.
2140          </p></td></tr>
2141</table></div>
2142</div>
2143<div class="section">
2144<div class="titlepage"><div><div><h4 class="title">
2145<a name="boost_yap.manual.examples.calc1"></a><a class="link" href="manual.html#boost_yap.manual.examples.calc1" title="Calc1">Calc1</a>
2146</h4></div></div></div>
2147<p>
2148          This is the first of several calculator-building examples derived from
2149          Proto. This first one just builds lazy expressions with placeholders, and
2150          evaluates them. Here we can first see how much C++14-and-later language
2151          features help the end user — the Proto version is much, much longer.
2152        </p>
2153<p>
2154</p>
2155<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2156
2157<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2158
2159
2160<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2161<span class="special">{</span>
2162    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
2163
2164    <span class="comment">// Displays "5"</span>
2165    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="number">1</span><span class="identifier">_p</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2166
2167    <span class="comment">// Displays "6"</span>
2168    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">*</span> <span class="number">2</span><span class="identifier">_p</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2169
2170    <span class="comment">// Displays "0.5"</span>
2171    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="special">(</span><span class="number">1</span><span class="identifier">_p</span> <span class="special">-</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">)</span> <span class="special">/</span> <span class="number">2</span><span class="identifier">_p</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2172
2173    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2174<span class="special">}</span>
2175</pre>
2176<p>
2177        </p>
2178</div>
2179<div class="section">
2180<div class="titlepage"><div><div><h4 class="title">
2181<a name="boost_yap.manual.examples.calc2"></a><a class="link" href="manual.html#boost_yap.manual.examples.calc2" title="Calc2">Calc2</a>
2182</h4></div></div></div>
2183<p>
2184          The Proto Calc2 example turns the expressions from Calc1 into callable
2185          objects. Using Boost.YAP you can do this in two ways.
2186        </p>
2187<p>
2188          You can just use lambdas to wrap the expressions:
2189        </p>
2190<p>
2191</p>
2192<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2193
2194<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2195
2196
2197<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2198<span class="special">{</span>
2199    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
2200
2201    <span class="keyword">auto</span> <span class="identifier">expr_1</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">+</span> <span class="number">2.0</span><span class="special">;</span>
2202
2203    <span class="keyword">auto</span> <span class="identifier">expr_1_fn</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">expr_1</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="special">{</span>
2204        <span class="keyword">return</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_1</span><span class="special">,</span> <span class="identifier">args</span><span class="special">...);</span>
2205    <span class="special">};</span>
2206
2207    <span class="keyword">auto</span> <span class="identifier">expr_2</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">*</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">;</span>
2208
2209    <span class="keyword">auto</span> <span class="identifier">expr_2_fn</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">expr_2</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="special">{</span>
2210        <span class="keyword">return</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_2</span><span class="special">,</span> <span class="identifier">args</span><span class="special">...);</span>
2211    <span class="special">};</span>
2212
2213    <span class="keyword">auto</span> <span class="identifier">expr_3</span> <span class="special">=</span> <span class="special">(</span><span class="number">1</span><span class="identifier">_p</span> <span class="special">-</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">)</span> <span class="special">/</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">;</span>
2214
2215    <span class="keyword">auto</span> <span class="identifier">expr_3_fn</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">expr_3</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="special">{</span>
2216        <span class="keyword">return</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_3</span><span class="special">,</span> <span class="identifier">args</span><span class="special">...);</span>
2217    <span class="special">};</span>
2218
2219    <span class="comment">// Displays "5"</span>
2220    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr_1_fn</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2221
2222    <span class="comment">// Displays "6"</span>
2223    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr_2_fn</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2224
2225    <span class="comment">// Displays "0.5"</span>
2226    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr_3_fn</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2227
2228    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2229<span class="special">}</span>
2230</pre>
2231<p>
2232        </p>
2233<p>
2234          Or you can use <code class="computeroutput"><a class="link" href="../boost/yap/make_expression_function.html" title="Function template make_expression_function">make_expression_function()</a></code>
2235          to make a callable object from your expression:
2236        </p>
2237<p>
2238</p>
2239<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2240
2241<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2242
2243
2244<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2245<span class="special">{</span>
2246    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
2247
2248    <span class="comment">// Displays "5"</span>
2249    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">make_expression_function</span><span class="special">(</span><span class="number">1</span><span class="identifier">_p</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2250
2251    <span class="comment">// Displays "6"</span>
2252    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">make_expression_function</span><span class="special">(</span><span class="number">1</span><span class="identifier">_p</span> <span class="special">*</span> <span class="number">2</span><span class="identifier">_p</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2253
2254    <span class="comment">// Displays "0.5"</span>
2255    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">make_expression_function</span><span class="special">((</span><span class="number">1</span><span class="identifier">_p</span> <span class="special">-</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">)</span> <span class="special">/</span> <span class="number">2</span><span class="identifier">_p</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2256
2257    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2258<span class="special">}</span>
2259</pre>
2260<p>
2261        </p>
2262</div>
2263<div class="section">
2264<div class="titlepage"><div><div><h4 class="title">
2265<a name="boost_yap.manual.examples.calc3"></a><a class="link" href="manual.html#boost_yap.manual.examples.calc3" title="Calc3">Calc3</a>
2266</h4></div></div></div>
2267<p>
2268          Here, we introduce a <a class="link" href="concepts.html#boost_yap.concepts.transform">Transform</a>
2269          used to calculate expression arity, and <code class="computeroutput"><span class="keyword">static_assert</span><span class="special">()</span></code> that the number of parameters passed
2270          by the caller matches the arity.
2271        </p>
2272<div class="note"><table border="0" summary="Note">
2273<tr>
2274<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
2275<th align="left">Note</th>
2276</tr>
2277<tr><td align="left" valign="top"><p>
2278            The <code class="computeroutput"><span class="identifier">get_arity</span></code> <a class="link" href="concepts.html#boost_yap.concepts.transform">Transform</a>
2279            doesn't produce an <a class="link" href="concepts.html#boost_yap.concepts.expression">Expression</a>,
2280            and it does not have to. <a class="link" href="concepts.html#boost_yap.concepts.transform">Transforms</a>
2281            may produce <a class="link" href="concepts.html#boost_yap.concepts.expression">Expressions</a>
2282            or arbitrary values. They may also have arbitrary side effects, and may
2283            be stateful.
2284          </p></td></tr>
2285</table></div>
2286<p>
2287</p>
2288<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2289
2290<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">maximum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2291
2292<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2293
2294
2295<span class="comment">// Look! A transform!  This one transforms the expression tree into the arity</span>
2296<span class="comment">// of the expression, based on its placeholders.</span>
2297<span class="keyword">struct</span> <span class="identifier">get_arity</span>
2298<span class="special">{</span>
2299    <span class="comment">// Base case 1: Match a placeholder terminal, and return its arity as the</span>
2300    <span class="comment">// result.</span>
2301    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">&gt;</span>
2302    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
2303                                      <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;)</span>
2304    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;;</span> <span class="special">}</span>
2305
2306    <span class="comment">// Base case 2: Match any other terminal.  Return 0; non-placeholders do</span>
2307    <span class="comment">// not contribute to arity.</span>
2308    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
2309    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span> <span class="identifier">T</span> <span class="special">&amp;&amp;)</span>
2310    <span class="special">{</span>
2311        <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
2312        <span class="keyword">return</span> <span class="number">0</span><span class="identifier">_c</span><span class="special">;</span>
2313    <span class="special">}</span>
2314
2315    <span class="comment">// Recursive case: Match any expression not covered above, and return the</span>
2316    <span class="comment">// maximum of its children's arities.</span>
2317    <span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Arg</span><span class="special">&gt;</span>
2318    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">&gt;,</span> <span class="identifier">Arg</span> <span class="special">&amp;&amp;...</span> <span class="identifier">arg</span><span class="special">)</span>
2319    <span class="special">{</span>
2320        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">maximum</span><span class="special">(</span>
2321            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span>
2322                <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span>
2323                    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Arg</span><span class="special">&gt;(</span><span class="identifier">arg</span><span class="special">)),</span>
2324                    <span class="identifier">get_arity</span><span class="special">{}</span>
2325                <span class="special">)...</span>
2326            <span class="special">)</span>
2327        <span class="special">);</span>
2328    <span class="special">}</span>
2329<span class="special">};</span>
2330
2331<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2332<span class="special">{</span>
2333    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
2334
2335    <span class="comment">// These lambdas wrap our expressions as callables, and allow us to check</span>
2336    <span class="comment">// the arity of each as we call it.</span>
2337
2338    <span class="keyword">auto</span> <span class="identifier">expr_1</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">+</span> <span class="number">2.0</span><span class="special">;</span>
2339
2340    <span class="keyword">auto</span> <span class="identifier">expr_1_fn</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">expr_1</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="special">{</span>
2341        <span class="keyword">auto</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">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr_1</span><span class="special">,</span> <span class="identifier">get_arity</span><span class="special">{});</span>
2342        <span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">arity</span><span class="special">.</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">args</span><span class="special">),</span> <span class="string">"Called with wrong number of args."</span><span class="special">);</span>
2343        <span class="keyword">return</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_1</span><span class="special">,</span> <span class="identifier">args</span><span class="special">...);</span>
2344    <span class="special">};</span>
2345
2346    <span class="keyword">auto</span> <span class="identifier">expr_2</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">*</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">;</span>
2347
2348    <span class="keyword">auto</span> <span class="identifier">expr_2_fn</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">expr_2</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="special">{</span>
2349        <span class="keyword">auto</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">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr_2</span><span class="special">,</span> <span class="identifier">get_arity</span><span class="special">{});</span>
2350        <span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">arity</span><span class="special">.</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">args</span><span class="special">),</span> <span class="string">"Called with wrong number of args."</span><span class="special">);</span>
2351        <span class="keyword">return</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_2</span><span class="special">,</span> <span class="identifier">args</span><span class="special">...);</span>
2352    <span class="special">};</span>
2353
2354    <span class="keyword">auto</span> <span class="identifier">expr_3</span> <span class="special">=</span> <span class="special">(</span><span class="number">1</span><span class="identifier">_p</span> <span class="special">-</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">)</span> <span class="special">/</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">;</span>
2355
2356    <span class="keyword">auto</span> <span class="identifier">expr_3_fn</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">expr_3</span><span class="special">](</span><span class="keyword">auto</span> <span class="special">&amp;&amp;...</span> <span class="identifier">args</span><span class="special">)</span> <span class="special">{</span>
2357        <span class="keyword">auto</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">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr_3</span><span class="special">,</span> <span class="identifier">get_arity</span><span class="special">{});</span>
2358        <span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">arity</span><span class="special">.</span><span class="identifier">value</span> <span class="special">==</span> <span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">args</span><span class="special">),</span> <span class="string">"Called with wrong number of args."</span><span class="special">);</span>
2359        <span class="keyword">return</span> <span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr_3</span><span class="special">,</span> <span class="identifier">args</span><span class="special">...);</span>
2360    <span class="special">};</span>
2361
2362    <span class="comment">// Displays "5"</span>
2363    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr_1_fn</span><span class="special">(</span><span class="number">3.0</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2364
2365    <span class="comment">// Displays "6"</span>
2366    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr_2_fn</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2367
2368    <span class="comment">// Displays "0.5"</span>
2369    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr_3_fn</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2370
2371    <span class="comment">// Static-asserts with "Called with wrong number of args."</span>
2372    <span class="comment">//std::cout &lt;&lt; expr_3_fn(3.0) &lt;&lt; std::endl;</span>
2373
2374    <span class="comment">// Static-asserts with "Called with wrong number of args."</span>
2375    <span class="comment">//std::cout &lt;&lt; expr_3_fn(3.0, 2.0, 1.0) &lt;&lt; std::endl;</span>
2376
2377    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2378<span class="special">}</span>
2379</pre>
2380<p>
2381        </p>
2382</div>
2383<div class="section">
2384<div class="titlepage"><div><div><h4 class="title">
2385<a name="boost_yap.manual.examples.lazy_vector"></a><a class="link" href="manual.html#boost_yap.manual.examples.lazy_vector" title="Lazy Vector">Lazy Vector</a>
2386</h4></div></div></div>
2387<p>
2388          Finally, it starts to get interesting! This example shows how you can add
2389          plus and other operations to sequences of data without creating temporaries
2390          and allocating memory.
2391        </p>
2392<div class="note"><table border="0" summary="Note">
2393<tr>
2394<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
2395<th align="left">Note</th>
2396</tr>
2397<tr><td align="left" valign="top"><p>
2398            In this example, we see a terminal type that owns the storage of its
2399            value, a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>.
2400            See the Vector example later on to see a terminal type that does not.
2401          </p></td></tr>
2402</table></div>
2403<p>
2404</p>
2405<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2406
2407<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
2408<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
2409<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2410<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
2411
2412
2413<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2414<span class="keyword">struct</span> <span class="identifier">lazy_vector_expr</span><span class="special">;</span>
2415
2416
2417<span class="comment">// This transform turns a terminal of std::vector&lt;double&gt; into a terminal</span>
2418<span class="comment">// containing the nth double in that vector.  Think of it as turning our</span>
2419<span class="comment">// expression of vectors into an expression of scalars.</span>
2420<span class="keyword">struct</span> <span class="identifier">take_nth</span>
2421<span class="special">{</span>
2422    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span>
2423    <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">);</span>
2424
2425    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">;</span>
2426<span class="special">};</span>
2427
2428<span class="comment">// A custom expression template that defines lazy + and - operators that</span>
2429<span class="comment">// produce expressions, and an eager [] operator that returns the nth element</span>
2430<span class="comment">// of the expression.</span>
2431<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2432<span class="keyword">struct</span> <span class="identifier">lazy_vector_expr</span>
2433<span class="special">{</span>
2434    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
2435
2436    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
2437
2438    <span class="comment">// Note that this does not return an expression; it is greedily evaluated.</span>
2439    <span class="keyword">auto</span> <span class="keyword">operator</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">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
2440<span class="special">};</span>
2441
2442<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">)</span>
2443<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="identifier">lazy_vector_expr</span><span class="special">)</span>
2444
2445<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2446<span class="keyword">auto</span> <span class="identifier">lazy_vector_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;::</span><span class="keyword">operator</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">n</span><span class="special">)</span> <span class="keyword">const</span>
2447<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">take_nth</span><span class="special">{</span><span class="identifier">n</span><span class="special">}));</span> <span class="special">}</span>
2448
2449<span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span>
2450<span class="identifier">take_nth</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2451<span class="special">{</span>
2452    <span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">n</span><span class="special">];</span>
2453    <span class="comment">// This move is something of a hack; we're forcing Yap to take a copy of x</span>
2454    <span class="comment">// by using std::move().  The move indicates that the terminal should keep</span>
2455    <span class="comment">// the value of x (since, being an rvalue, it may be a temporary), rather</span>
2456    <span class="comment">// than a reference to x.  See the "How Expression Operands Are Treated"</span>
2457    <span class="comment">// section of the tutorial for details.</span>
2458    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">));</span>
2459<span class="special">}</span>
2460
2461<span class="comment">// In order to define the += operator with the semantics we want, it's</span>
2462<span class="comment">// convenient to derive a terminal type from a terminal instantiation of</span>
2463<span class="comment">// lazy_vector_expr.  Note that we could have written a template</span>
2464<span class="comment">// specialization here instead -- either one would work.  That would of course</span>
2465<span class="comment">// have required more typing.</span>
2466<span class="keyword">struct</span> <span class="identifier">lazy_vector</span> <span class="special">:</span>
2467    <span class="identifier">lazy_vector_expr</span><span class="special">&lt;</span>
2468        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
2469        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span>
2470    <span class="special">&gt;</span>
2471<span class="special">{</span>
2472    <span class="identifier">lazy_vector</span> <span class="special">()</span> <span class="special">{}</span>
2473
2474    <span class="keyword">explicit</span> <span class="identifier">lazy_vector</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">vec</span><span class="special">)</span>
2475    <span class="special">{</span> <span class="identifier">elements</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">vec</span><span class="special">));</span> <span class="special">}</span>
2476
2477    <span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2478    <span class="identifier">lazy_vector</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=</span> <span class="special">(</span><span class="identifier">lazy_vector_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">)</span>
2479    <span class="special">{</span>
2480        <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">this_vec</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">value</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
2481        <span class="keyword">for</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">size</span> <span class="special">=</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">this_vec</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="identifier">i</span> <span class="special">&lt;</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>
2482            <span class="identifier">this_vec</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">+=</span> <span class="identifier">rhs</span><span class="special">[</span><span class="identifier">i</span><span class="special">];</span>
2483        <span class="special">}</span>
2484        <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
2485    <span class="special">}</span>
2486<span class="special">};</span>
2487
2488<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
2489<span class="special">{</span>
2490    <span class="identifier">lazy_vector</span> <span class="identifier">v1</span><span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">1.0</span><span class="special">)};</span>
2491    <span class="identifier">lazy_vector</span> <span class="identifier">v2</span><span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">2.0</span><span class="special">)};</span>
2492    <span class="identifier">lazy_vector</span> <span class="identifier">v3</span><span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">4</span><span class="special">,</span> <span class="number">3.0</span><span class="special">)};</span>
2493
2494    <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>
2495    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">d1</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
2496
2497    <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>
2498    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'{'</span> <span class="special">&lt;&lt;</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">1</span><span class="special">]</span>
2499              <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
2500
2501    <span class="comment">// This expression is disallowed because it does not conform to the</span>
2502    <span class="comment">// implicit grammar.  operator+= is only defined on terminals, not</span>
2503    <span class="comment">// arbitrary expressions.</span>
2504    <span class="comment">// (v2 + v3) += v1;</span>
2505
2506    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2507<span class="special">}</span>
2508</pre>
2509<p>
2510        </p>
2511</div>
2512<div class="section">
2513<div class="titlepage"><div><div><h4 class="title">
2514<a name="boost_yap.manual.examples.self_evaluating_expressions"></a><a class="link" href="manual.html#boost_yap.manual.examples.self_evaluating_expressions" title="Self-Evaluating Expressions">Self-Evaluating
2515        Expressions</a>
2516</h4></div></div></div>
2517<p>
2518          In most of the examples, we've seen Boost.YAP expressions captured, transformed,
2519          and/or evaluated either manually, or within certain operations that always
2520          do certain transformations (as in the <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code> in the <a class="link" href="manual.html#boost_yap.manual.examples.lazy_vector" title="Lazy Vector">Lazy
2521          Vector</a> example).
2522        </p>
2523<p>
2524          Sometimes, you want the transfrmations to happen just before a Boost.YAP
2525          expression is used by non-Boost.YAP-aware code. At other times, you might
2526          want an entire Boost.YAP expression to be evaluated if it appears by itself
2527          in a statement (i.e. as an expression statement).
2528        </p>
2529<p>
2530          This example uses C++17's <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">()</span></code>,
2531          simply because it makes the example shorter and easier to digest. The
2532          <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span>
2533          <span class="special">()</span></code> bits are not strictly necessary.
2534        </p>
2535<p>
2536</p>
2537<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2538
2539<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2540<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">fold</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2541<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">maximum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2542
2543<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
2544<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
2545<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2546<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
2547
2548
2549<span class="comment">// A super-basic matrix type, and a few associated operations.</span>
2550<span class="keyword">struct</span> <span class="identifier">matrix</span>
2551<span class="special">{</span>
2552    <span class="identifier">matrix</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">values_</span><span class="special">(),</span> <span class="identifier">rows_</span><span class="special">(</span><span class="number">0</span><span class="special">),</span> <span class="identifier">cols_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
2553
2554    <span class="identifier">matrix</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">rows</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">cols</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">values_</span><span class="special">(</span><span class="identifier">rows</span> <span class="special">*</span> <span class="identifier">cols</span><span class="special">),</span> <span class="identifier">rows_</span><span class="special">(</span><span class="identifier">rows</span><span class="special">),</span> <span class="identifier">cols_</span><span class="special">(</span><span class="identifier">cols</span><span class="special">)</span>
2555    <span class="special">{</span>
2556        <span class="identifier">assert</span><span class="special">(</span><span class="number">0</span> <span class="special">&lt;</span> <span class="identifier">rows</span><span class="special">);</span>
2557        <span class="identifier">assert</span><span class="special">(</span><span class="number">0</span> <span class="special">&lt;</span> <span class="identifier">cols</span><span class="special">);</span>
2558    <span class="special">}</span>
2559
2560    <span class="keyword">int</span> <span class="identifier">rows</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">rows_</span><span class="special">;</span> <span class="special">}</span>
2561    <span class="keyword">int</span> <span class="identifier">cols</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">cols_</span><span class="special">;</span> <span class="special">}</span>
2562
2563    <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">r</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span>
2564    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">values_</span><span class="special">[</span><span class="identifier">r</span> <span class="special">*</span> <span class="identifier">cols_</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">];</span> <span class="special">}</span>
2565    <span class="keyword">double</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">r</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">c</span><span class="special">)</span>
2566    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">values_</span><span class="special">[</span><span class="identifier">r</span> <span class="special">*</span> <span class="identifier">cols_</span> <span class="special">+</span> <span class="identifier">c</span><span class="special">];</span> <span class="special">}</span>
2567
2568<span class="keyword">private</span><span class="special">:</span>
2569    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">values_</span><span class="special">;</span>
2570    <span class="keyword">int</span> <span class="identifier">rows_</span><span class="special">;</span>
2571    <span class="keyword">int</span> <span class="identifier">cols_</span><span class="special">;</span>
2572<span class="special">};</span>
2573
2574<span class="identifier">matrix</span> <span class="keyword">operator</span><span class="special">*(</span><span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span>
2575<span class="special">{</span>
2576    <span class="identifier">matrix</span> <span class="identifier">retval</span> <span class="special">=</span> <span class="identifier">lhs</span><span class="special">;</span>
2577    <span class="keyword">for</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">i</span> <span class="special">&lt;</span> <span class="identifier">retval</span><span class="special">.</span><span class="identifier">rows</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
2578        <span class="keyword">for</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="identifier">j</span> <span class="special">&lt;</span> <span class="identifier">retval</span><span class="special">.</span><span class="identifier">cols</span><span class="special">();</span> <span class="special">++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span>
2579            <span class="identifier">retval</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="special">*=</span> <span class="identifier">x</span><span class="special">;</span>
2580        <span class="special">}</span>
2581    <span class="special">}</span>
2582    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
2583<span class="special">}</span>
2584<span class="identifier">matrix</span> <span class="keyword">operator</span><span class="special">*(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">lhs</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">lhs</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
2585
2586<span class="identifier">matrix</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">)</span>
2587<span class="special">{</span>
2588    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">rows</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">rows</span><span class="special">());</span>
2589    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">cols</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">cols</span><span class="special">());</span>
2590    <span class="identifier">matrix</span> <span class="identifier">retval</span> <span class="special">=</span> <span class="identifier">lhs</span><span class="special">;</span>
2591    <span class="keyword">for</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">i</span> <span class="special">&lt;</span> <span class="identifier">retval</span><span class="special">.</span><span class="identifier">rows</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
2592        <span class="keyword">for</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="identifier">j</span> <span class="special">&lt;</span> <span class="identifier">retval</span><span class="special">.</span><span class="identifier">cols</span><span class="special">();</span> <span class="special">++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span>
2593            <span class="identifier">retval</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="special">+=</span> <span class="identifier">rhs</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">);</span>
2594        <span class="special">}</span>
2595    <span class="special">}</span>
2596    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
2597<span class="special">}</span>
2598
2599<span class="comment">// daxpy() means Double-precision AX Plus Y.  This crazy name comes from BLAS.</span>
2600<span class="comment">// It is more efficient than a naive implementation, because it does not</span>
2601<span class="comment">// create temporaries.  The covnention of using Y as an out-parameter comes</span>
2602<span class="comment">// from FORTRAN BLAS.</span>
2603<span class="identifier">matrix</span> <span class="special">&amp;</span> <span class="identifier">daxpy</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span>
2604<span class="special">{</span>
2605    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">rows</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">rows</span><span class="special">());</span>
2606    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">cols</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">cols</span><span class="special">());</span>
2607    <span class="keyword">for</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">i</span> <span class="special">&lt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">rows</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
2608        <span class="keyword">for</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="identifier">j</span> <span class="special">&lt;</span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">cols</span><span class="special">();</span> <span class="special">++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span>
2609            <span class="identifier">y</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="special">+=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">);</span>
2610        <span class="special">}</span>
2611    <span class="special">}</span>
2612    <span class="keyword">return</span> <span class="identifier">y</span><span class="special">;</span>
2613<span class="special">}</span>
2614
2615<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2616<span class="keyword">struct</span> <span class="identifier">self_evaluating_expr</span><span class="special">;</span>
2617
2618<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2619<span class="keyword">auto</span> <span class="identifier">evaluate_matrix_expr</span><span class="special">(</span><span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">);</span>
2620
2621<span class="comment">// This is the primary template for our expression template.  If you assign a</span>
2622<span class="comment">// self_evaluating_expr to a matrix, its conversion operator transforms and</span>
2623<span class="comment">// evaluates the expression with a call to evaluate_matrix_expr().</span>
2624<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2625<span class="keyword">struct</span> <span class="identifier">self_evaluating_expr</span>
2626<span class="special">{</span>
2627    <span class="keyword">operator</span> <span class="keyword">auto</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
2628
2629    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
2630
2631    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
2632<span class="special">};</span>
2633
2634<span class="comment">// This is a specialization of our expression template for assignment</span>
2635<span class="comment">// expressions.  The destructor transforms and evaluates via a call to</span>
2636<span class="comment">// evaluate_matrix_expr(), and then assigns the result to the variable on the</span>
2637<span class="comment">// left side of the assignment.</span>
2638<span class="comment">//</span>
2639<span class="comment">// In a production implementation, you'd need to have specializations for</span>
2640<span class="comment">// plus_assign, minus_assign, etc.</span>
2641<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2642<span class="keyword">struct</span> <span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">assign</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2643<span class="special">{</span>
2644    <span class="special">~</span><span class="identifier">self_evaluating_expr</span><span class="special">();</span>
2645
2646    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">assign</span><span class="special">;</span>
2647
2648    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
2649<span class="special">};</span>
2650
2651<span class="keyword">struct</span> <span class="identifier">use_daxpy</span>
2652<span class="special">{</span>
2653    <span class="comment">// A plus-expression, which may be of the form double * matrix + matrix,</span>
2654    <span class="comment">// or may be something else.  Since our daxpy() above requires a mutable</span>
2655    <span class="comment">// "y", we only need to match a mutable lvalue matrix reference here.</span>
2656    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2657    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span>
2658        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span><span class="special">&gt;,</span>
2659        <span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">,</span>
2660        <span class="identifier">matrix</span> <span class="special">&amp;</span> <span class="identifier">m</span><span class="special">)</span>
2661    <span class="special">{</span>
2662        <span class="comment">// Here, we transform the left-hand side into a pair if it's the</span>
2663        <span class="comment">// double * matrix operation we're looking for.  Otherwise, we just</span>
2664        <span class="comment">// get a copy of the left side expression.</span>
2665        <span class="comment">//</span>
2666        <span class="comment">// Note that this is a bit of a cheat, done for clarity.  If we pass a</span>
2667        <span class="comment">// larger expression that happens to contain a double * matrix</span>
2668        <span class="comment">// subexpression, that subexpression will be transformed into a tuple!</span>
2669        <span class="comment">// In production code, this transform should probably only be</span>
2670        <span class="comment">// performed on an expression with all terminal members.</span>
2671        <span class="keyword">auto</span> <span class="identifier">lhs</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span>
2672            <span class="identifier">expr</span><span class="special">,</span>
2673            <span class="special">[](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special">&gt;,</span>
2674               <span class="keyword">double</span> <span class="identifier">d</span><span class="special">,</span>
2675               <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">m</span><span class="special">)</span> <span class="special">{</span>
2676                <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&amp;&gt;(</span><span class="identifier">d</span><span class="special">,</span> <span class="identifier">m</span><span class="special">);</span>
2677            <span class="special">});</span>
2678
2679        <span class="comment">// If we got back a copy of expr above, just re-construct the</span>
2680        <span class="comment">// expression this function mathes; in other words, do not effectively</span>
2681        <span class="comment">// transform anything.  Otherwise, replace the expression matched by</span>
2682        <span class="comment">// this function with a call to daxpy().</span>
2683        <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">is_expr</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">)&gt;::</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{</span>
2684            <span class="keyword">return</span> <span class="identifier">expr</span> <span class="special">+</span> <span class="identifier">m</span><span class="special">;</span>
2685        <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
2686            <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">daxpy</span><span class="special">)(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">lhs</span><span class="special">.</span><span class="identifier">second</span><span class="special">,</span> <span class="identifier">m</span><span class="special">);</span>
2687        <span class="special">}</span>
2688    <span class="special">}</span>
2689<span class="special">};</span>
2690
2691
2692<span class="comment">// This is the heart of what self_evaluating_expr does.  If we had other</span>
2693<span class="comment">// optimizations/transformations we wanted to do, we'd put them in this</span>
2694<span class="comment">// function, either before or after the use_daxpy transformation.</span>
2695<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2696<span class="keyword">auto</span> <span class="identifier">evaluate_matrix_expr</span><span class="special">(</span><span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2697<span class="special">{</span>
2698    <span class="keyword">auto</span> <span class="identifier">daxpy_form</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">use_daxpy</span><span class="special">{});</span>
2699    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">daxpy_form</span><span class="special">);</span>
2700<span class="special">}</span>
2701
2702<span class="keyword">template</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2703<span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;::</span><span class="keyword">operator</span> <span class="keyword">auto</span><span class="special">()</span> <span class="keyword">const</span>
2704<span class="special">{</span>
2705    <span class="keyword">return</span> <span class="identifier">evaluate_matrix_expr</span><span class="special">(*</span><span class="keyword">this</span><span class="special">);</span>
2706<span class="special">}</span>
2707
2708<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2709<span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">assign</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;::</span>
2710    <span class="special">~</span><span class="identifier">self_evaluating_expr</span><span class="special">()</span>
2711<span class="special">{</span>
2712    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
2713    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">elements</span><span class="special">[</span><span class="number">0</span><span class="identifier">_c</span><span class="special">])</span> <span class="special">=</span> <span class="identifier">evaluate_matrix_expr</span><span class="special">(</span><span class="identifier">elements</span><span class="special">[</span><span class="number">1</span><span class="identifier">_c</span><span class="special">]);</span>
2714<span class="special">}</span>
2715
2716<span class="comment">// In order to define the = operator with the semantics we want, it's</span>
2717<span class="comment">// convenient to derive a terminal type from a terminal instantiation of</span>
2718<span class="comment">// self_evaluating_expr.  Note that we could have written a template</span>
2719<span class="comment">// specialization here instead -- either one would work.  That would of course</span>
2720<span class="comment">// have required more typing.</span>
2721<span class="keyword">struct</span> <span class="identifier">self_evaluating</span> <span class="special">:</span>
2722    <span class="identifier">self_evaluating_expr</span><span class="special">&lt;</span>
2723        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
2724        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">matrix</span><span class="special">&gt;</span>
2725    <span class="special">&gt;</span>
2726<span class="special">{</span>
2727    <span class="identifier">self_evaluating</span><span class="special">()</span> <span class="special">{}</span>
2728
2729    <span class="keyword">explicit</span> <span class="identifier">self_evaluating</span><span class="special">(</span><span class="identifier">matrix</span> <span class="identifier">m</span><span class="special">)</span>
2730    <span class="special">{</span> <span class="identifier">elements</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">matrix</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">m</span><span class="special">));</span> <span class="special">}</span>
2731
2732    <span class="identifier">BOOST_YAP_USER_ASSIGN_OPERATOR</span><span class="special">(</span><span class="identifier">self_evaluating_expr</span><span class="special">,</span> <span class="special">::</span><span class="identifier">self_evaluating_expr</span><span class="special">);</span>
2733<span class="special">};</span>
2734
2735<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">self_evaluating_expr</span><span class="special">,</span> <span class="identifier">self_evaluating_expr</span><span class="special">)</span>
2736<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">self_evaluating_expr</span><span class="special">,</span> <span class="identifier">self_evaluating_expr</span><span class="special">)</span>
2737<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">self_evaluating_expr</span><span class="special">,</span> <span class="identifier">self_evaluating_expr</span><span class="special">)</span>
2738
2739
2740<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
2741<span class="special">{</span>
2742    <span class="identifier">matrix</span> <span class="identifier">identity</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">2</span><span class="special">);</span>
2743    <span class="identifier">identity</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span> <span class="special">=</span> <span class="number">1.0</span><span class="special">;</span>
2744    <span class="identifier">identity</span><span class="special">(</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> <span class="special">=</span> <span class="number">1.0</span><span class="special">;</span>
2745
2746    <span class="comment">// These are YAP-ified terminal expressions.</span>
2747    <span class="identifier">self_evaluating</span> <span class="identifier">m1</span><span class="special">(</span><span class="identifier">identity</span><span class="special">);</span>
2748    <span class="identifier">self_evaluating</span> <span class="identifier">m2</span><span class="special">(</span><span class="identifier">identity</span><span class="special">);</span>
2749    <span class="identifier">self_evaluating</span> <span class="identifier">m3</span><span class="special">(</span><span class="identifier">identity</span><span class="special">);</span>
2750
2751    <span class="comment">// This transforms the YAP expression to use daxpy(), so it creates no</span>
2752    <span class="comment">// temporaries.  The transform happens in the destructor of the</span>
2753    <span class="comment">// assignment-expression specialization of self_evaluating_expr.</span>
2754    <span class="identifier">m1</span> <span class="special">=</span> <span class="number">3.0</span> <span class="special">*</span> <span class="identifier">m2</span> <span class="special">+</span> <span class="identifier">m3</span><span class="special">;</span>
2755
2756    <span class="comment">// Same as above, except that it uses the matrix conversion operator on</span>
2757    <span class="comment">// the self_evaluating_expr primary template, because here we're assigning</span>
2758    <span class="comment">// a YAP expression to a non-YAP-ified matrix.</span>
2759    <span class="identifier">matrix</span> <span class="identifier">m_result_1</span> <span class="special">=</span> <span class="number">3.0</span> <span class="special">*</span> <span class="identifier">m2</span> <span class="special">+</span> <span class="identifier">m3</span><span class="special">;</span>
2760
2761    <span class="comment">// Creates temporaries and does not use daxpy(), because the A * X + Y</span>
2762    <span class="comment">// pattern does not occur within the expression.</span>
2763    <span class="identifier">matrix</span> <span class="identifier">m_result_2</span> <span class="special">=</span> <span class="number">3.0</span> <span class="special">*</span> <span class="identifier">m2</span><span class="special">;</span>
2764
2765    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2766<span class="special">}</span>
2767</pre>
2768<p>
2769        </p>
2770</div>
2771<div class="section">
2772<div class="titlepage"><div><div><h4 class="title">
2773<a name="boost_yap.manual.examples.tarray"></a><a class="link" href="manual.html#boost_yap.manual.examples.tarray" title="TArray">TArray</a>
2774</h4></div></div></div>
2775<p>
2776          Proto refers to this as the "mini-library for linear algebra"
2777          example. It shows how quite complicated expressions involving sequences
2778          can be evaluated elementwise, requiring no temporaries.
2779        </p>
2780<div class="note"><table border="0" summary="Note">
2781<tr>
2782<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
2783<th align="left">Note</th>
2784</tr>
2785<tr><td align="left" valign="top"><p>
2786            The original Proto example used a terminal that contained an array of
2787            three <code class="computeroutput"><span class="keyword">int</span></code>s; Boost.YAP cannot
2788            represent this, and so this example uses a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span></code>
2789            instead. Boost.YAP decays <code class="computeroutput"><span class="keyword">int</span><span class="special">[</span><span class="number">3</span><span class="special">]</span></code>
2790            to <code class="computeroutput"><span class="keyword">int</span> <span class="special">*</span></code>,
2791            since that is what is done in a C++ expression. See <a class="link" href="manual.html#boost_yap.manual.how_expression_operands_are_treated" title="How Expression Operands Are Treated">How
2792            Expression Operands Are Treated</a> for details.
2793          </p></td></tr>
2794</table></div>
2795<p>
2796</p>
2797<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2798<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">print</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2799
2800<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
2801<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2802
2803
2804<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2805<span class="keyword">struct</span> <span class="identifier">tarray_expr</span><span class="special">;</span>
2806
2807
2808<span class="keyword">struct</span> <span class="identifier">take_nth</span>
2809<span class="special">{</span>
2810    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span>
2811    <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">);</span>
2812
2813    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">;</span>
2814<span class="special">};</span>
2815
2816<span class="comment">// Another custom expression template.  In this case, we static_assert() that</span>
2817<span class="comment">// it only gets instantiated with terminals with pre-approved value types.</span>
2818<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2819<span class="keyword">struct</span> <span class="identifier">tarray_expr</span>
2820<span class="special">{</span>
2821    <span class="comment">// Make sure that, if this expression is a terminal, its value is one we</span>
2822    <span class="comment">// want to support.  Note that the presence of expr_kind::expr_ref makes</span>
2823    <span class="comment">// life slightly more difficult; we have to account for int const &amp; and</span>
2824    <span class="comment">// int &amp; as well as int.</span>
2825    <span class="keyword">static_assert</span><span class="special">(</span>
2826        <span class="identifier">Kind</span> <span class="special">!=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span> <span class="special">||</span>
2827        <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">Tuple</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&amp;&gt;&gt;{}</span> <span class="special">||</span>
2828        <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">Tuple</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="special">&amp;&gt;&gt;{}</span> <span class="special">||</span>
2829        <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">Tuple</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;{}</span> <span class="special">||</span>
2830        <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">Tuple</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;&gt;{},</span>
2831        <span class="string">"tarray_expr instantiated with an unsupported terminal type."</span>
2832    <span class="special">);</span>
2833
2834    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
2835
2836    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
2837
2838    <span class="keyword">int</span> <span class="keyword">operator</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">n</span><span class="special">)</span> <span class="keyword">const</span>
2839    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">take_nth</span><span class="special">{</span><span class="identifier">n</span><span class="special">}));</span> <span class="special">}</span>
2840<span class="special">};</span>
2841
2842<span class="comment">// Define operators +, -, *, and /.</span>
2843<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">)</span>
2844<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">)</span>
2845<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">)</span>
2846<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">divides</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">)</span>
2847
2848
2849<span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span>
2850<span class="identifier">take_nth</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2851<span class="special">{</span>
2852    <span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">n</span><span class="special">];</span>
2853    <span class="comment">// Again, this is the move hack to get x into the resulting terminal as a</span>
2854    <span class="comment">// value instead of a reference.</span>
2855    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">));</span>
2856<span class="special">}</span>
2857
2858
2859<span class="comment">// Stream-out operators for the two kinds of terminals we support.</span>
2860
2861<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">expr</span><span class="special">)</span>
2862<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="char">'{'</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">;</span> <span class="special">}</span>
2863
2864<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;</span> <span class="identifier">expr</span><span class="special">)</span>
2865<span class="special">{</span>
2866    <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
2867    <span class="keyword">return</span> <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="char">'{'</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="char">'}'</span><span class="special">;</span>
2868<span class="special">}</span>
2869
2870<span class="comment">// Stream-out operators for general expressions.  Note that we have to treat</span>
2871<span class="comment">// the reference case separately; this also could have been done using</span>
2872<span class="comment">// constexpr if in a single function template.</span>
2873
2874<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2875<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">expr_ref</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2876<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">deref</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span> <span class="special">}</span>
2877
2878<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
2879<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2880<span class="special">{</span>
2881    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">Kind</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span> <span class="special">||</span> <span class="identifier">Kind</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">minus</span><span class="special">)</span>
2882        <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="char">'('</span><span class="special">;</span>
2883    <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op_string</span><span class="special">(</span><span class="identifier">Kind</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span> <span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
2884    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">Kind</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span> <span class="special">||</span> <span class="identifier">Kind</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">minus</span><span class="special">)</span>
2885        <span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="char">')'</span><span class="special">;</span>
2886    <span class="keyword">return</span> <span class="identifier">os</span><span class="special">;</span>
2887<span class="special">}</span>
2888
2889
2890<span class="comment">// Since we want different behavior on terminals than on other kinds of</span>
2891<span class="comment">// expressions, we create a custom type that does so.</span>
2892<span class="keyword">struct</span> <span class="identifier">tarray</span> <span class="special">:</span>
2893    <span class="identifier">tarray_expr</span><span class="special">&lt;</span>
2894        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
2895        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;</span>
2896    <span class="special">&gt;</span>
2897<span class="special">{</span>
2898    <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>
2899    <span class="special">{</span>
2900        <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>
2901        <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>
2902        <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>
2903    <span class="special">}</span>
2904
2905    <span class="keyword">explicit</span> <span class="identifier">tarray</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">)</span>
2906    <span class="special">{</span>
2907        <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">a</span><span class="special">[</span><span class="number">0</span><span class="special">];</span>
2908        <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">a</span><span class="special">[</span><span class="number">1</span><span class="special">];</span>
2909        <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">a</span><span class="special">[</span><span class="number">2</span><span class="special">];</span>
2910    <span class="special">}</span>
2911
2912    <span class="keyword">int</span> <span class="special">&amp;</span> <span class="keyword">operator</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>
2913    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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>
2914
2915    <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="keyword">operator</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="keyword">const</span>
2916    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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>
2917
2918    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
2919    <span class="identifier">tarray</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span>
2920    <span class="special">{</span>
2921        <span class="comment">// We use as_expr() here to make sure that the value passed to</span>
2922        <span class="comment">// assign() is an expression.  as_expr() simply forwards expressions</span>
2923        <span class="comment">// through, and wraps non-expressions as terminals.</span>
2924        <span class="keyword">return</span> <span class="identifier">assign</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">&lt;</span> <span class="special">::</span><span class="identifier">tarray_expr</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">));</span>
2925    <span class="special">}</span>
2926
2927    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
2928    <span class="identifier">tarray</span> <span class="special">&amp;</span> <span class="identifier">printAssign</span> <span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2929    <span class="special">{</span>
2930        <span class="special">*</span><span class="keyword">this</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">;</span>
2931        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="keyword">this</span> <span class="special">&lt;&lt;</span> <span class="string">" = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2932        <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
2933    <span class="special">}</span>
2934
2935<span class="keyword">private</span><span class="special">:</span>
2936    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
2937    <span class="identifier">tarray</span> <span class="special">&amp;</span> <span class="identifier">assign</span> <span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2938    <span class="special">{</span>
2939        <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>
2940        <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>
2941        <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>
2942        <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
2943    <span class="special">}</span>
2944<span class="special">};</span>
2945
2946
2947<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
2948<span class="special">{</span>
2949    <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>
2950
2951    <span class="identifier">tarray</span> <span class="identifier">b</span><span class="special">;</span>
2952
2953    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2954    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2955
2956    <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>
2957
2958    <span class="identifier">tarray</span> <span class="identifier">c</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span>
2959
2960    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">c</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2961
2962    <span class="identifier">a</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
2963
2964    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2965    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2966    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">c</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2967
2968    <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>
2969
2970    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2971
2972    <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>
2973
2974    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
2975<span class="special">}</span>
2976</pre>
2977<p>
2978        </p>
2979</div>
2980<div class="section">
2981<div class="titlepage"><div><div><h4 class="title">
2982<a name="boost_yap.manual.examples.vec3"></a><a class="link" href="manual.html#boost_yap.manual.examples.vec3" title="Vec3">Vec3</a>
2983</h4></div></div></div>
2984<p>
2985          An example using 3-space vectors, a bit like the tarray example.
2986        </p>
2987<p>
2988</p>
2989<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2990
2991<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
2992<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
2993
2994
2995<span class="keyword">struct</span> <span class="identifier">take_nth</span>
2996<span class="special">{</span>
2997    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
2998    <span class="special">{</span>
2999        <span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">n</span><span class="special">];</span>
3000        <span class="comment">// The move forces the terminal to store the value of x, not a</span>
3001        <span class="comment">// reference.</span>
3002        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">));</span>
3003    <span class="special">}</span>
3004
3005    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">;</span>
3006<span class="special">};</span>
3007
3008<span class="comment">// Since this example doesn't constrain the operators defined on its</span>
3009<span class="comment">// expressions, we can just use boost::yap::expression&lt;&gt; as the expression</span>
3010<span class="comment">// template.</span>
3011<span class="keyword">using</span> <span class="identifier">vec3_terminal</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
3012    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
3013    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;&gt;</span>
3014<span class="special">&gt;;</span>
3015
3016<span class="comment">// Customize the terminal type we use by adding index and assignment</span>
3017<span class="comment">// operations.</span>
3018<span class="keyword">struct</span> <span class="identifier">vec3</span> <span class="special">:</span> <span class="identifier">vec3_terminal</span>
3019<span class="special">{</span>
3020    <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>
3021    <span class="special">{</span>
3022        <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>
3023        <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>
3024        <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>
3025    <span class="special">}</span>
3026
3027    <span class="keyword">explicit</span> <span class="identifier">vec3</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">)</span>
3028    <span class="special">{</span>
3029        <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">a</span><span class="special">[</span><span class="number">0</span><span class="special">];</span>
3030        <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">a</span><span class="special">[</span><span class="number">1</span><span class="special">];</span>
3031        <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">a</span><span class="special">[</span><span class="number">2</span><span class="special">];</span>
3032    <span class="special">}</span>
3033
3034    <span class="keyword">int</span> <span class="special">&amp;</span> <span class="keyword">operator</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>
3035    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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>
3036
3037    <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="keyword">operator</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="keyword">const</span>
3038    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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>
3039
3040    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3041    <span class="identifier">vec3</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">t</span><span class="special">)</span>
3042    <span class="special">{</span>
3043        <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">t</span><span class="special">);</span>
3044        <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">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">take_nth</span><span class="special">{</span><span class="number">0</span><span class="special">}));</span>
3045        <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">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">take_nth</span><span class="special">{</span><span class="number">1</span><span class="special">}));</span>
3046        <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">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">take_nth</span><span class="special">{</span><span class="number">2</span><span class="special">}));</span>
3047        <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
3048    <span class="special">}</span>
3049
3050    <span class="keyword">void</span> <span class="identifier">print</span><span class="special">()</span> <span class="keyword">const</span>
3051    <span class="special">{</span>
3052        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="char">'{'</span> <span class="special">&lt;&lt;</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span>
3053                  <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span>
3054                  <span class="special">&lt;&lt;</span> <span class="string">", "</span> <span class="special">&lt;&lt;</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span>
3055                  <span class="special">&lt;&lt;</span> <span class="char">'}'</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3056    <span class="special">}</span>
3057<span class="special">};</span>
3058
3059<span class="comment">// This is a stateful transform that keeps a running count of the terminals it</span>
3060<span class="comment">// has seen.</span>
3061<span class="keyword">struct</span> <span class="identifier">count_leaves_impl</span>
3062<span class="special">{</span>
3063    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">vec3_terminal</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3064    <span class="special">{</span>
3065        <span class="identifier">value</span> <span class="special">+=</span> <span class="number">1</span><span class="special">;</span>
3066        <span class="keyword">return</span> <span class="identifier">expr</span><span class="special">;</span>
3067    <span class="special">}</span>
3068
3069    <span class="keyword">int</span> <span class="identifier">value</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
3070<span class="special">};</span>
3071
3072<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
3073<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">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3074<span class="special">{</span>
3075    <span class="identifier">count_leaves_impl</span> <span class="identifier">impl</span><span class="special">;</span>
3076    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">impl</span><span class="special">);</span>
3077    <span class="keyword">return</span> <span class="identifier">impl</span><span class="special">.</span><span class="identifier">value</span><span class="special">;</span>
3078<span class="special">}</span>
3079
3080
3081<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
3082<span class="special">{</span>
3083    <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>
3084
3085    <span class="identifier">c</span> <span class="special">=</span> <span class="number">4</span><span class="special">;</span>
3086
3087    <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>
3088    <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>
3089    <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>
3090
3091    <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>
3092
3093    <span class="identifier">a</span><span class="special">.</span><span class="identifier">print</span><span class="special">();</span>
3094
3095    <span class="identifier">vec3</span> <span class="identifier">d</span><span class="special">;</span>
3096    <span class="keyword">auto</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>
3097    <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">expr1</span><span class="special">;</span>
3098    <span class="identifier">d</span><span class="special">.</span><span class="identifier">print</span><span class="special">();</span>
3099
3100    <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>
3101    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">num</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3102
3103    <span class="identifier">num</span> <span class="special">=</span> <span class="identifier">count_leaves</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>
3104    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">num</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3105
3106    <span class="identifier">num</span> <span class="special">=</span> <span class="identifier">count_leaves</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>
3107    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">num</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3108
3109    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3110<span class="special">}</span>
3111</pre>
3112<p>
3113        </p>
3114</div>
3115<div class="section">
3116<div class="titlepage"><div><div><h4 class="title">
3117<a name="boost_yap.manual.examples.vector"></a><a class="link" href="manual.html#boost_yap.manual.examples.vector" title="Vector">Vector</a>
3118</h4></div></div></div>
3119<p>
3120          So far we've only seen examples with custom terminals that own the values
3121          in the expressions we operate on. What happens when you've got types that
3122          you want to operate on, non-intrusively? Here's how you might do it with
3123          <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;&gt;</span></code>s:
3124        </p>
3125<p>
3126</p>
3127<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
3128
3129<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
3130<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
3131
3132
3133<span class="keyword">struct</span> <span class="identifier">take_nth</span>
3134<span class="special">{</span>
3135    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3136    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
3137                     <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">vec</span><span class="special">)</span>
3138    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">vec</span><span class="special">[</span><span class="identifier">n</span><span class="special">]);</span> <span class="special">}</span>
3139
3140    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">;</span>
3141<span class="special">};</span>
3142
3143<span class="comment">// A stateful transform that records whether all the std::vector&lt;&gt; terminals</span>
3144<span class="comment">// it has seen are equal to the given size.</span>
3145<span class="keyword">struct</span> <span class="identifier">equal_sizes_impl</span>
3146<span class="special">{</span>
3147    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3148    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
3149                     <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">vec</span><span class="special">)</span>
3150    <span class="special">{</span>
3151        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">expr_size</span> <span class="special">=</span> <span class="identifier">vec</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span>
3152        <span class="keyword">if</span> <span class="special">(</span><span class="identifier">expr_size</span> <span class="special">!=</span> <span class="identifier">size</span><span class="special">)</span>
3153            <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
3154        <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3155    <span class="special">}</span>
3156
3157    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="keyword">const</span> <span class="identifier">size</span><span class="special">;</span>
3158    <span class="keyword">bool</span> <span class="identifier">value</span><span class="special">;</span>
3159<span class="special">};</span>
3160
3161<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
3162<span class="keyword">bool</span> <span class="identifier">equal_sizes</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">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3163<span class="special">{</span>
3164    <span class="identifier">equal_sizes_impl</span> <span class="identifier">impl</span><span class="special">{</span><span class="identifier">size</span><span class="special">,</span> <span class="keyword">true</span><span class="special">};</span>
3165    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">impl</span><span class="special">);</span>
3166    <span class="keyword">return</span> <span class="identifier">impl</span><span class="special">.</span><span class="identifier">value</span><span class="special">;</span>
3167<span class="special">}</span>
3168
3169
3170<span class="comment">// Assigns some expression e to the given vector by evaluating e elementwise,</span>
3171<span class="comment">// to avoid temporaries and allocations.</span>
3172<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
3173<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">vec</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
3174<span class="special">{</span>
3175    <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">e</span><span class="special">);</span>
3176    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">equal_sizes</span><span class="special">(</span><span class="identifier">vec</span><span class="special">.</span><span class="identifier">size</span><span class="special">(),</span> <span class="identifier">expr</span><span class="special">));</span>
3177    <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">size</span> <span class="special">=</span> <span class="identifier">vec</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="identifier">i</span> <span class="special">&lt;</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>
3178        <span class="identifier">vec</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span>
3179            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">take_nth</span><span class="special">{</span><span class="identifier">i</span><span class="special">}));</span>
3180    <span class="special">}</span>
3181    <span class="keyword">return</span> <span class="identifier">vec</span><span class="special">;</span>
3182<span class="special">}</span>
3183
3184<span class="comment">// As assign() above, just using +=.</span>
3185<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
3186<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="keyword">operator</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">vec</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
3187<span class="special">{</span>
3188    <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">e</span><span class="special">);</span>
3189    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">equal_sizes</span><span class="special">(</span><span class="identifier">vec</span><span class="special">.</span><span class="identifier">size</span><span class="special">(),</span> <span class="identifier">expr</span><span class="special">));</span>
3190    <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">size</span> <span class="special">=</span> <span class="identifier">vec</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="identifier">i</span> <span class="special">&lt;</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>
3191        <span class="identifier">vec</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special">+=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span>
3192            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">take_nth</span><span class="special">{</span><span class="identifier">i</span><span class="special">}));</span>
3193    <span class="special">}</span>
3194    <span class="keyword">return</span> <span class="identifier">vec</span><span class="special">;</span>
3195<span class="special">}</span>
3196
3197<span class="comment">// Define a type trait that identifies std::vectors.</span>
3198<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3199<span class="keyword">struct</span> <span class="identifier">is_vector</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">false_type</span> <span class="special">{};</span>
3200
3201<span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
3202<span class="keyword">struct</span> <span class="identifier">is_vector</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;&gt;</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
3203
3204<span class="comment">// Define all the expression-returning numeric operators we need.  Each will</span>
3205<span class="comment">// accept any std::vector&lt;&gt; as any of its arguments, and then any value in the</span>
3206<span class="comment">// remaining argument, if any -- some of the operators below are unary.</span>
3207<span class="identifier">BOOST_YAP_USER_UDT_UNARY_OPERATOR</span><span class="special">(</span><span class="identifier">negate</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// -</span>
3208<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// *</span>
3209<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">divides</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// /</span>
3210<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">modulus</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// %</span>
3211<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// +</span>
3212<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// -</span>
3213<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">less</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// &lt;</span>
3214<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">greater</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// &gt;</span>
3215<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">less_equal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// &lt;=</span>
3216<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">greater_equal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// &gt;=</span>
3217<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">equal_to</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// ==</span>
3218<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">not_equal_to</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// !=</span>
3219<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">logical_or</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// ||</span>
3220<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">logical_and</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// &amp;&amp;</span>
3221<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_and</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// &amp;</span>
3222<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_or</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// |</span>
3223<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_xor</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_vector</span><span class="special">);</span> <span class="comment">// ^</span>
3224
3225<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
3226<span class="special">{</span>
3227    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
3228    <span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
3229    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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>
3230    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">e</span><span class="special">(</span><span class="identifier">n</span><span class="special">);</span>
3231
3232    <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">&lt;</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
3233    <span class="special">{</span>
3234        <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>
3235        <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>
3236        <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>
3237        <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>
3238    <span class="special">}</span>
3239
3240    <span class="comment">// After this point, no allocations occur.</span>
3241
3242    <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>
3243    <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>
3244
3245    <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">&lt;</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>
3246
3247    <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>
3248    <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>
3249
3250    <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">&lt;</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
3251    <span class="special">{</span>
3252        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span>
3253            <span class="special">&lt;&lt;</span> <span class="string">" a("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3254            <span class="special">&lt;&lt;</span> <span class="string">" b("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3255            <span class="special">&lt;&lt;</span> <span class="string">" c("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">c</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3256            <span class="special">&lt;&lt;</span> <span class="string">" d("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">d</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3257            <span class="special">&lt;&lt;</span> <span class="string">" e("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3258            <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3259    <span class="special">}</span>
3260
3261    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3262<span class="special">}</span>
3263</pre>
3264<p>
3265        </p>
3266<div class="note"><table border="0" summary="Note">
3267<tr>
3268<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
3269<th align="left">Note</th>
3270</tr>
3271<tr><td align="left" valign="top"><p>
3272            Though this example only provides overloads for the operations we want
3273            to define over <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;&gt;</span></code>s,
3274            the result of each of those operations is an <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code>,
3275            which uses <span class="bold"><strong>all</strong></span> the operator overloads.
3276            If we wanted to restrict the operations on the results too, we could
3277            have defined a custom expression template with the desired operations,
3278            and used that instead of <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code>
3279            in the operator macros.
3280          </p></td></tr>
3281</table></div>
3282</div>
3283<div class="section">
3284<div class="titlepage"><div><div><h4 class="title">
3285<a name="boost_yap.manual.examples.mixed"></a><a class="link" href="manual.html#boost_yap.manual.examples.mixed" title="Mixed">Mixed</a>
3286</h4></div></div></div>
3287<p>
3288          This is a lot like the previous Vector example, except that it operates
3289          on <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;&gt;</span></code>s
3290          and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;&gt;</span></code>s
3291          in the same expression.
3292        </p>
3293<p>
3294</p>
3295<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
3296
3297<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">complex</span><span class="special">&gt;</span>
3298<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">list</span><span class="special">&gt;</span>
3299<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
3300<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
3301
3302
3303<span class="comment">// This wrapper makes the pattern matching in transforms below (like deref and</span>
3304<span class="comment">// incr) a lot easier to write.</span>
3305<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
3306<span class="keyword">struct</span> <span class="identifier">iter_wrapper</span>
3307<span class="special">{</span>
3308    <span class="identifier">Iter</span> <span class="identifier">it</span><span class="special">;</span>
3309<span class="special">};</span>
3310
3311<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
3312<span class="keyword">auto</span> <span class="identifier">make_iter_wrapper</span> <span class="special">(</span><span class="identifier">Iter</span> <span class="identifier">it</span><span class="special">)</span>
3313<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">iter_wrapper</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;{</span><span class="identifier">it</span><span class="special">};</span> <span class="special">}</span>
3314
3315
3316<span class="comment">// A container -&gt; wrapped-begin transform.</span>
3317<span class="keyword">struct</span> <span class="identifier">begin</span>
3318<span class="special">{</span>
3319    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Cont</span><span class="special">&gt;</span>
3320    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
3321                     <span class="identifier">Cont</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">cont</span><span class="special">)</span>
3322        <span class="special">-&gt;</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">make_iter_wrapper</span><span class="special">(</span><span class="identifier">cont</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())))</span>
3323    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">make_iter_wrapper</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="special">}</span>
3324<span class="special">};</span>
3325
3326<span class="comment">// A wrapped-iterator -&gt; dereferenced value transform.</span>
3327<span class="keyword">struct</span> <span class="identifier">deref</span>
3328<span class="special">{</span>
3329    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
3330    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
3331                     <span class="identifier">iter_wrapper</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;</span> <span class="identifier">wrapper</span><span class="special">)</span>
3332        <span class="special">-&gt;</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(*</span><span class="identifier">wrapper</span><span class="special">.</span><span class="identifier">it</span><span class="special">))</span>
3333    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(*</span><span class="identifier">wrapper</span><span class="special">.</span><span class="identifier">it</span><span class="special">);</span> <span class="special">}</span>
3334<span class="special">};</span>
3335
3336<span class="comment">// A wrapped-iterator increment transform, using side effects.</span>
3337<span class="keyword">struct</span> <span class="identifier">incr</span>
3338<span class="special">{</span>
3339    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
3340    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
3341                     <span class="identifier">iter_wrapper</span><span class="special">&lt;</span><span class="identifier">Iter</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">wrapper</span><span class="special">)</span>
3342        <span class="special">-&gt;</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">wrapper</span><span class="special">.</span><span class="identifier">it</span><span class="special">))</span>
3343    <span class="special">{</span>
3344        <span class="special">++</span><span class="identifier">wrapper</span><span class="special">.</span><span class="identifier">it</span><span class="special">;</span>
3345        <span class="comment">// Since this transform is valuable for its side effects, and thus the</span>
3346        <span class="comment">// result of the transform is ignored, we could return anything here.</span>
3347        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">wrapper</span><span class="special">.</span><span class="identifier">it</span><span class="special">);</span>
3348    <span class="special">}</span>
3349<span class="special">};</span>
3350
3351
3352<span class="comment">// The implementation of elementwise evaluation of expressions of sequences;</span>
3353<span class="comment">// all the later operations use this one.</span>
3354<span class="keyword">template</span> <span class="special">&lt;</span>
3355    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">Cont</span><span class="special">,</span>
3356    <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span>
3357    <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span>
3358    <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span>
3359    <span class="keyword">typename</span> <span class="identifier">Op</span>
3360<span class="special">&gt;</span>
3361<span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">op_assign</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">Op</span> <span class="special">&amp;&amp;</span> <span class="identifier">op</span><span class="special">)</span>
3362<span class="special">{</span>
3363    <span class="keyword">decltype</span><span class="special">(</span><span class="keyword">auto</span><span class="special">)</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">e</span><span class="special">);</span>
3364    <span class="comment">// Transform the expression of sequences into an expression of</span>
3365    <span class="comment">// begin-iterators.</span>
3366    <span class="keyword">auto</span> <span class="identifier">expr2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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">begin</span><span class="special">{});</span>
3367    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="special">&amp;&amp;</span> <span class="identifier">x</span> <span class="special">:</span> <span class="identifier">cont</span><span class="special">)</span> <span class="special">{</span>
3368        <span class="comment">// Transform the expression of iterators into an expression of</span>
3369        <span class="comment">// pointed-to-values, evaluate the resulting expression, and call op()</span>
3370        <span class="comment">// with the result of the evaluation.</span>
3371        <span class="identifier">op</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr2</span><span class="special">,</span> <span class="identifier">deref</span><span class="special">{})));</span>
3372        <span class="comment">// Transform the expression of iterators into an ignored value; as a</span>
3373        <span class="comment">// side effect, increment the iterators in the expression.</span>
3374        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr2</span><span class="special">,</span> <span class="identifier">incr</span><span class="special">{});</span>
3375    <span class="special">}</span>
3376    <span class="keyword">return</span> <span class="identifier">cont</span><span class="special">;</span>
3377<span class="special">}</span>
3378
3379<span class="keyword">template</span> <span class="special">&lt;</span>
3380    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">Cont</span><span class="special">,</span>
3381    <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span>
3382    <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span>
3383    <span class="keyword">typename</span> <span class="identifier">Expr</span>
3384<span class="special">&gt;</span>
3385<span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">assign</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3386<span class="special">{</span>
3387    <span class="keyword">return</span> <span class="identifier">op_assign</span><span class="special">(</span><span class="identifier">cont</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">,</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">cont_value</span><span class="special">,</span> <span class="keyword">auto</span> <span class="special">&amp;&amp;</span> <span class="identifier">expr_value</span><span class="special">)</span> <span class="special">{</span>
3388        <span class="identifier">cont_value</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">expr_value</span><span class="special">)&gt;(</span><span class="identifier">expr_value</span><span class="special">);</span>
3389    <span class="special">});</span>
3390<span class="special">}</span>
3391
3392<span class="keyword">template</span> <span class="special">&lt;</span>
3393    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">Cont</span><span class="special">,</span>
3394    <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span>
3395    <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span>
3396    <span class="keyword">typename</span> <span class="identifier">Expr</span>
3397<span class="special">&gt;</span>
3398<span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3399<span class="special">{</span>
3400    <span class="keyword">return</span> <span class="identifier">op_assign</span><span class="special">(</span><span class="identifier">cont</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">,</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">cont_value</span><span class="special">,</span> <span class="keyword">auto</span> <span class="special">&amp;&amp;</span> <span class="identifier">expr_value</span><span class="special">)</span> <span class="special">{</span>
3401        <span class="identifier">cont_value</span> <span class="special">+=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">expr_value</span><span class="special">)&gt;(</span><span class="identifier">expr_value</span><span class="special">);</span>
3402    <span class="special">});</span>
3403<span class="special">}</span>
3404
3405<span class="keyword">template</span> <span class="special">&lt;</span>
3406    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">Cont</span><span class="special">,</span>
3407    <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span>
3408    <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">,</span>
3409    <span class="keyword">typename</span> <span class="identifier">Expr</span>
3410<span class="special">&gt;</span>
3411<span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">-=</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3412<span class="special">{</span>
3413    <span class="keyword">return</span> <span class="identifier">op_assign</span><span class="special">(</span><span class="identifier">cont</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">,</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">cont_value</span><span class="special">,</span> <span class="keyword">auto</span> <span class="special">&amp;&amp;</span> <span class="identifier">expr_value</span><span class="special">)</span> <span class="special">{</span>
3414        <span class="identifier">cont_value</span> <span class="special">-=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">expr_value</span><span class="special">)&gt;(</span><span class="identifier">expr_value</span><span class="special">);</span>
3415    <span class="special">});</span>
3416<span class="special">}</span>
3417
3418<span class="comment">// A type trait that identifies std::vectors and std::lists.</span>
3419<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3420<span class="keyword">struct</span> <span class="identifier">is_mixed</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">false_type</span> <span class="special">{};</span>
3421
3422<span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
3423<span class="keyword">struct</span> <span class="identifier">is_mixed</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;&gt;</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
3424
3425<span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
3426<span class="keyword">struct</span> <span class="identifier">is_mixed</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">&gt;&gt;</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">true_type</span> <span class="special">{};</span>
3427
3428<span class="comment">// Define expression-producing operators over std::vectors and std::lists.</span>
3429<span class="identifier">BOOST_YAP_USER_UDT_UNARY_OPERATOR</span><span class="special">(</span><span class="identifier">negate</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// -</span>
3430<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// *</span>
3431<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">divides</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// /</span>
3432<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">modulus</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// %</span>
3433<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// +</span>
3434<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// -</span>
3435<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">less</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// &lt;</span>
3436<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">greater</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// &gt;</span>
3437<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">less_equal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// &lt;=</span>
3438<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">greater_equal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// &gt;=</span>
3439<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">equal_to</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// ==</span>
3440<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">not_equal_to</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// !=</span>
3441<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">logical_or</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// ||</span>
3442<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">logical_and</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// &amp;&amp;</span>
3443<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_and</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// &amp;</span>
3444<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_or</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// |</span>
3445<span class="identifier">BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_xor</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">,</span> <span class="identifier">is_mixed</span><span class="special">);</span> <span class="comment">// ^</span>
3446
3447<span class="comment">// Define a type that can resolve to any overload of std::sin().</span>
3448<span class="keyword">struct</span> <span class="identifier">sin_t</span>
3449<span class="special">{</span>
3450    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3451    <span class="identifier">T</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
3452    <span class="special">{</span>
3453        <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">x</span><span class="special">);</span>
3454    <span class="special">}</span>
3455<span class="special">};</span>
3456
3457<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
3458<span class="special">{</span>
3459    <span class="keyword">int</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
3460    <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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>
3461    <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">e</span><span class="special">;</span>
3462    <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;</span> <span class="identifier">f</span><span class="special">;</span>
3463
3464    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
3465    <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">&lt;</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
3466    <span class="special">{</span>
3467        <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>
3468        <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>
3469        <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>
3470        <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>
3471        <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>
3472        <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">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span>
3473    <span class="special">}</span>
3474
3475    <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>
3476    <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>
3477    <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">&lt;</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>
3478
3479    <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>
3480    <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>
3481
3482    <span class="keyword">auto</span> <span class="identifier">sin</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">sin_t</span><span class="special">{});</span>
3483    <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">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="number">0.2</span><span class="special">,</span> <span class="number">1.2</span><span class="special">));</span>
3484
3485    <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</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>
3486    <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;&gt;::</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>
3487    <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">&lt;</span> <span class="identifier">n</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
3488    <span class="special">{</span>
3489        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span>
3490            <span class="special">&lt;&lt;</span> <span class="string">"a("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3491            <span class="special">&lt;&lt;</span> <span class="string">" b("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3492            <span class="special">&lt;&lt;</span> <span class="string">" c("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">c</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3493            <span class="special">&lt;&lt;</span> <span class="string">" d("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">d</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span>
3494            <span class="special">&lt;&lt;</span> <span class="string">" e("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">ei</span><span class="special">++</span>
3495            <span class="special">&lt;&lt;</span> <span class="string">" f("</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="string">") = "</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">fi</span><span class="special">++</span>
3496            <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3497    <span class="special">}</span>
3498
3499    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3500<span class="special">}</span>
3501</pre>
3502<p>
3503        </p>
3504</div>
3505<div class="section">
3506<div class="titlepage"><div><div><h4 class="title">
3507<a name="boost_yap.manual.examples.map_assign"></a><a class="link" href="manual.html#boost_yap.manual.examples.map_assign" title="Map Assign">Map Assign</a>
3508</h4></div></div></div>
3509<p>
3510          An implementation of <code class="computeroutput"><span class="identifier">map_list_of</span><span class="special">()</span></code> from Boost.Assign using Boost.YAP.
3511        </p>
3512<p>
3513</p>
3514<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
3515
3516<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">map</span><span class="special">&gt;</span>
3517<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
3518
3519
3520<span class="comment">// This transform applies all the call-subexpressions in a map_list_of</span>
3521<span class="comment">// expression (a nested chain of call operations) as a side effect; the</span>
3522<span class="comment">// expression returned by the transform is ignored.</span>
3523<span class="keyword">template</span> <span class="special">&lt;</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">Allocator</span><span class="special">&gt;</span>
3524<span class="keyword">struct</span> <span class="identifier">map_list_of_transform</span>
3525<span class="special">{</span>
3526    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Key2</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Value2</span><span class="special">&gt;</span>
3527    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;,</span>
3528                     <span class="identifier">Fn</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Key2</span> <span class="special">&amp;&amp;</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">Value2</span> <span class="special">&amp;&amp;</span> <span class="identifier">value</span><span class="special">)</span>
3529    <span class="special">{</span>
3530        <span class="comment">// Recurse into the function subexpression.  Remember, transform()</span>
3531        <span class="comment">// walks the nodes in an expression tree looking for matches.  Once it</span>
3532        <span class="comment">// finds a match, it is finished with that matching subtree.  So</span>
3533        <span class="comment">// without this recursive call, only the top-level call expression is</span>
3534        <span class="comment">// matched by transform().</span>
3535        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span>
3536            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">minimal_expr</span><span class="special">&gt;(</span><span class="identifier">fn</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
3537        <span class="identifier">map</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span>
3538            <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Key2</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">key</span><span class="special">),</span>
3539            <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Value2</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">value</span><span class="special">)</span>
3540        <span class="special">);</span>
3541        <span class="comment">// All we care about are the side effects of this transform, so we can</span>
3542        <span class="comment">// return any old thing here.</span>
3543        <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3544    <span class="special">}</span>
3545
3546    <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">map</span><span class="special">;</span>
3547<span class="special">};</span>
3548
3549
3550<span class="comment">// A custom expression template type for map_list_of expressions.  We only</span>
3551<span class="comment">// need support for the call operator and an implicit conversion to a</span>
3552<span class="comment">// std::map.</span>
3553<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
3554<span class="keyword">struct</span> <span class="identifier">map_list_of_expr</span>
3555<span class="special">{</span>
3556    <span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="keyword">const</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
3557
3558    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
3559
3560    <span class="keyword">template</span> <span class="special">&lt;</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">Allocator</span><span class="special">&gt;</span>
3561    <span class="keyword">operator</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span> <span class="special">()</span> <span class="keyword">const</span>
3562    <span class="special">{</span>
3563        <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span> <span class="identifier">retval</span><span class="special">;</span>
3564        <span class="identifier">map_list_of_transform</span><span class="special">&lt;</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span> <span class="identifier">transform</span><span class="special">{</span><span class="identifier">retval</span><span class="special">};</span>
3565        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">transform</span><span class="special">);</span>
3566        <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
3567    <span class="special">}</span>
3568
3569    <span class="identifier">BOOST_YAP_USER_CALL_OPERATOR_N</span><span class="special">(::</span><span class="identifier">map_list_of_expr</span><span class="special">,</span> <span class="number">2</span><span class="special">)</span>
3570<span class="special">};</span>
3571
3572<span class="comment">// A tag type for creating the map_list_of function terminal.</span>
3573<span class="keyword">struct</span> <span class="identifier">map_list_of_tag</span> <span class="special">{};</span>
3574
3575<span class="keyword">auto</span> <span class="identifier">map_list_of</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">&lt;</span><span class="identifier">map_list_of_expr</span><span class="special">&gt;(</span><span class="identifier">map_list_of_tag</span><span class="special">{});</span>
3576
3577
3578<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
3579<span class="special">{</span>
3580    <span class="comment">// Initialize a map:</span>
3581    <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">op</span> <span class="special">=</span>
3582        <span class="identifier">map_list_of</span>
3583            <span class="special">(</span><span class="string">"&lt;"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span>
3584            <span class="special">(</span><span class="string">"&lt;="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span>
3585            <span class="special">(</span><span class="string">"&gt;"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
3586            <span class="special">(</span><span class="string">"&gt;="</span><span class="special">,</span><span class="number">4</span><span class="special">)</span>
3587            <span class="special">(</span><span class="string">"="</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
3588            <span class="special">(</span><span class="string">"&lt;&gt;"</span><span class="special">,</span><span class="number">6</span><span class="special">)</span>
3589        <span class="special">;</span>
3590
3591    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\"&lt;\"  --&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"&lt;"</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3592    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\"&lt;=\" --&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"&lt;="</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3593    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\"&gt;\"  --&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"&gt;"</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3594    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\"&gt;=\" --&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"&gt;="</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3595    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\"=\"  --&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"="</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3596    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\"&lt;&gt;\" --&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"&lt;&gt;"</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
3597
3598    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3599<span class="special">}</span>
3600</pre>
3601<p>
3602        </p>
3603<div class="note"><table border="0" summary="Note">
3604<tr>
3605<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
3606<th align="left">Note</th>
3607</tr>
3608<tr><td align="left" valign="top"><p>
3609            <code class="computeroutput"><span class="identifier">map_list_of_expr</span></code> defines
3610            a generic call operator that matches any call, including one with the
3611            wrong number of arguments. This could be fixed by adding a <code class="computeroutput"><span class="keyword">static_assert</span><span class="special">()</span></code>
3612            to the <code class="computeroutput"><span class="identifier">map_list_of_expr</span></code>
3613            template, or by hand-writing the call operator with SFNIAE or concept
3614            constraints.
3615          </p></td></tr>
3616</table></div>
3617</div>
3618<div class="section">
3619<div class="titlepage"><div><div><h4 class="title">
3620<a name="boost_yap.manual.examples.future_group"></a><a class="link" href="manual.html#boost_yap.manual.examples.future_group" title="Future Group">Future Group</a>
3621</h4></div></div></div>
3622<p>
3623          An implementation of Howard Hinnant's design for <span class="emphasis"><em>future groups</em></span>.
3624        </p>
3625<p>
3626</p>
3627<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
3628
3629<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">concat</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
3630
3631
3632<span class="comment">// A custom expression template for future groups.  It supports operators ||</span>
3633<span class="comment">// and &amp;&amp;.</span>
3634<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
3635<span class="keyword">struct</span> <span class="identifier">future_expr</span>
3636<span class="special">{</span>
3637    <span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="keyword">const</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
3638
3639    <span class="identifier">future_expr</span> <span class="special">(</span><span class="identifier">Tuple</span> <span class="special">&amp;&amp;</span> <span class="identifier">tuple</span><span class="special">)</span> <span class="special">:</span>
3640        <span class="identifier">elements</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Tuple</span> <span class="special">&amp;&amp;&gt;(</span><span class="identifier">tuple</span><span class="special">))</span>
3641    <span class="special">{}</span>
3642
3643    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
3644
3645    <span class="comment">// Returns the transformed/flattened expression.</span>
3646    <span class="keyword">auto</span> <span class="identifier">get</span> <span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
3647<span class="special">};</span>
3648
3649<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">logical_or</span><span class="special">,</span> <span class="identifier">future_expr</span><span class="special">,</span> <span class="identifier">future_expr</span><span class="special">)</span>
3650<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">logical_and</span><span class="special">,</span> <span class="identifier">future_expr</span><span class="special">,</span> <span class="identifier">future_expr</span><span class="special">)</span>
3651
3652<span class="comment">// A special-cased future terminal that matches the semantics from the</span>
3653<span class="comment">// original Proto example.</span>
3654<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3655<span class="keyword">struct</span> <span class="identifier">future</span> <span class="special">:</span>
3656    <span class="identifier">future_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span>
3657<span class="special">{</span>
3658    <span class="identifier">future</span> <span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">t</span> <span class="special">=</span> <span class="identifier">T</span><span class="special">())</span> <span class="special">:</span>
3659        <span class="identifier">future_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;{</span><span class="identifier">t</span><span class="special">})</span>
3660    <span class="special">{}</span>
3661
3662    <span class="identifier">T</span> <span class="identifier">get</span> <span class="special">()</span> <span class="keyword">const</span>
3663    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</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>
3664<span class="special">};</span>
3665
3666<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3667<span class="keyword">using</span> <span class="identifier">remove_cv_ref_t</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_cv_t</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference_t</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;;</span>
3668
3669<span class="comment">// A transform that flattens future expressions into a tuple.</span>
3670<span class="keyword">struct</span> <span class="identifier">future_transform</span>
3671<span class="special">{</span>
3672    <span class="comment">// Transform a terminal into its contained tuple.</span>
3673    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
3674    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span>
3675        <span class="identifier">future_expr</span><span class="special">&lt;</span>
3676            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
3677            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span>
3678        <span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">term</span>
3679    <span class="special">)</span> <span class="special">{</span>
3680        <span class="keyword">return</span> <span class="identifier">term</span><span class="special">.</span><span class="identifier">elements</span><span class="special">;</span>
3681    <span class="special">}</span>
3682
3683    <span class="comment">// Transform left || right -&gt; transform(left).</span>
3684    <span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
3685    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span>
3686        <span class="identifier">future_expr</span><span class="special">&lt;</span>
3687            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">logical_or</span><span class="special">,</span>
3688            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">&gt;</span>
3689        <span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">or_expr</span>
3690    <span class="special">)</span> <span class="special">{</span>
3691        <span class="comment">// Recursively transform the left side, and return the result.</span>
3692        <span class="comment">// Without the recursion, we might return a terminal expression here</span>
3693        <span class="comment">// insead of a tuple.</span>
3694        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">left</span><span class="special">(</span><span class="identifier">or_expr</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
3695    <span class="special">}</span>
3696
3697    <span class="comment">// Transform left &amp;&amp; right -&gt; concat(transform(left), transform(right)).</span>
3698    <span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
3699    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span>
3700        <span class="identifier">future_expr</span><span class="special">&lt;</span>
3701            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">logical_and</span><span class="special">,</span>
3702            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">&gt;</span>
3703        <span class="special">&gt;</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">and_expr</span>
3704    <span class="special">)</span> <span class="special">{</span>
3705        <span class="comment">// Recursively transform each side, then combine the resulting tuples</span>
3706        <span class="comment">// into a single tuple result.</span>
3707        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">concat</span><span class="special">(</span>
3708            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">left</span><span class="special">(</span><span class="identifier">and_expr</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">),</span>
3709            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">and_expr</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)</span>
3710        <span class="special">);</span>
3711    <span class="special">}</span>
3712<span class="special">};</span>
3713
3714
3715<span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
3716<span class="keyword">auto</span> <span class="identifier">future_expr</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">&gt;::</span><span class="identifier">get</span> <span class="special">()</span> <span class="keyword">const</span>
3717<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">future_transform</span><span class="special">{});</span> <span class="special">}</span>
3718
3719
3720<span class="comment">// TEST CASES</span>
3721<span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{};</span>
3722<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{};</span>
3723<span class="keyword">struct</span> <span class="identifier">C</span> <span class="special">{};</span>
3724
3725<span class="comment">// Called "vector" just so the code in main() will match the original Proto</span>
3726<span class="comment">// example.</span>
3727<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="special">...</span><span class="identifier">T</span><span class="special">&gt;</span>
3728<span class="keyword">using</span> <span class="identifier">vector</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;;</span>
3729
3730<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
3731<span class="special">{</span>
3732    <span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">;</span>
3733    <span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">B</span><span class="special">&gt;</span> <span class="identifier">b</span><span class="special">;</span>
3734    <span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">C</span><span class="special">&gt;</span> <span class="identifier">c</span><span class="special">;</span>
3735    <span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">B</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">ab</span><span class="special">;</span>
3736
3737    <span class="comment">// Verify that various future groups have the</span>
3738    <span class="comment">// correct return types.</span>
3739    <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>
3740    <span class="identifier">vector</span><span class="special">&lt;</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">&gt;</span>         <span class="identifier">t1</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">&amp;&amp;</span> <span class="identifier">b</span> <span class="special">&amp;&amp;</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span>
3741    <span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">C</span><span class="special">&gt;</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">&amp;&amp;</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span>
3742    <span class="identifier">vector</span><span class="special">&lt;</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">&gt;</span>         <span class="identifier">t3</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">a</span> <span class="special">&amp;&amp;</span> <span class="identifier">b</span> <span class="special">||</span> <span class="identifier">a</span> <span class="special">&amp;&amp;</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span>
3743    <span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">&gt;,</span> <span class="identifier">C</span><span class="special">&gt;</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">&amp;&amp;</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span>
3744
3745    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
3746<span class="special">}</span>
3747</pre>
3748<p>
3749        </p>
3750</div>
3751<div class="section">
3752<div class="titlepage"><div><div><h4 class="title">
3753<a name="boost_yap.manual.examples.autodiff"></a><a class="link" href="manual.html#boost_yap.manual.examples.autodiff" title="Autodiff">Autodiff</a>
3754</h4></div></div></div>
3755<p>
3756          Here we adapt an <a href="https://en.wikipedia.org/wiki/Automatic_differentiation" target="_top">automatic
3757          differentiation</a> library to use Boost.YAP for specifying the equations
3758          it operates on.
3759        </p>
3760<p>
3761          Autodiff is a pretty small library, and doesn't cover every possible input
3762          expression. What it covers is simple arithmetic, and the well-known functions
3763          <code class="computeroutput"><span class="identifier">sin</span></code>, <code class="computeroutput"><span class="identifier">cos</span></code>,
3764          <code class="computeroutput"><span class="identifier">sqrt</span></code>, and <code class="computeroutput"><span class="identifier">pow</span></code>.
3765        </p>
3766<p>
3767          Here is how you would form an input to the library using its API. This
3768          is taken from the test program that comes with the library.
3769        </p>
3770<p>
3771</p>
3772<pre class="programlisting"><span class="identifier">Node</span><span class="special">*</span> <span class="identifier">build_linear_fun1_manually</span><span class="special">(</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Node</span><span class="special">*&gt;&amp;</span> <span class="identifier">list</span><span class="special">)</span>
3773<span class="special">{</span>
3774	<span class="comment">//f(x1,x2,x3) = -5*x1+sin(10)*x1+10*x2-x3/6</span>
3775	<span class="identifier">PNode</span><span class="special">*</span> <span class="identifier">v5</span> <span class="special">=</span> <span class="identifier">create_param_node</span><span class="special">(-</span><span class="number">5</span><span class="special">);</span>
3776	<span class="identifier">PNode</span><span class="special">*</span> <span class="identifier">v10</span> <span class="special">=</span> <span class="identifier">create_param_node</span><span class="special">(</span><span class="number">10</span><span class="special">);</span>
3777	<span class="identifier">PNode</span><span class="special">*</span> <span class="identifier">v6</span> <span class="special">=</span> <span class="identifier">create_param_node</span><span class="special">(</span><span class="number">6</span><span class="special">);</span>
3778	<span class="identifier">VNode</span><span class="special">*</span>	<span class="identifier">x1</span> <span class="special">=</span> <span class="identifier">create_var_node</span><span class="special">();</span>
3779	<span class="identifier">VNode</span><span class="special">*</span>	<span class="identifier">x2</span> <span class="special">=</span> <span class="identifier">create_var_node</span><span class="special">();</span>
3780	<span class="identifier">VNode</span><span class="special">*</span>	<span class="identifier">x3</span> <span class="special">=</span> <span class="identifier">create_var_node</span><span class="special">();</span>
3781
3782	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op1</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_TIMES</span><span class="special">,</span><span class="identifier">v5</span><span class="special">,</span><span class="identifier">x1</span><span class="special">);</span>   <span class="comment">//op1 = v5*x1</span>
3783	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op2</span> <span class="special">=</span> <span class="identifier">create_uary_op_node</span><span class="special">(</span><span class="identifier">OP_SIN</span><span class="special">,</span><span class="identifier">v10</span><span class="special">);</span>         <span class="comment">//op2 = sin(v10)</span>
3784	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op3</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_TIMES</span><span class="special">,</span><span class="identifier">op2</span><span class="special">,</span><span class="identifier">x1</span><span class="special">);</span>  <span class="comment">//op3 = op2*x1</span>
3785	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op4</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_PLUS</span><span class="special">,</span><span class="identifier">op1</span><span class="special">,</span><span class="identifier">op3</span><span class="special">);</span>  <span class="comment">//op4 = op1 + op3</span>
3786	<span class="identifier">OPNode</span><span class="special">*</span>	<span class="identifier">op5</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_TIMES</span><span class="special">,</span><span class="identifier">v10</span><span class="special">,</span><span class="identifier">x2</span><span class="special">);</span>  <span class="comment">//op5 = v10*x2</span>
3787	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op6</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_PLUS</span><span class="special">,</span><span class="identifier">op4</span><span class="special">,</span><span class="identifier">op5</span><span class="special">);</span>  <span class="comment">//op6 = op4+op5</span>
3788	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op7</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_DIVID</span><span class="special">,</span><span class="identifier">x3</span><span class="special">,</span><span class="identifier">v6</span><span class="special">);</span>   <span class="comment">//op7 = x3/v6</span>
3789	<span class="identifier">OPNode</span><span class="special">*</span> <span class="identifier">op8</span> <span class="special">=</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span><span class="identifier">OP_MINUS</span><span class="special">,</span><span class="identifier">op6</span><span class="special">,</span><span class="identifier">op7</span><span class="special">);</span> <span class="comment">//op8 = op6 - op7</span>
3790	<span class="identifier">x1</span><span class="special">-&gt;</span><span class="identifier">val</span> <span class="special">=</span> <span class="special">-</span><span class="number">1.9</span><span class="special">;</span>
3791	<span class="identifier">x2</span><span class="special">-&gt;</span><span class="identifier">val</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
3792	<span class="identifier">x3</span><span class="special">-&gt;</span><span class="identifier">val</span> <span class="special">=</span> <span class="number">5.</span><span class="special">/</span><span class="number">6.</span><span class="special">;</span>
3793	<span class="identifier">list</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">x1</span><span class="special">);</span>
3794	<span class="identifier">list</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">x2</span><span class="special">);</span>
3795	<span class="identifier">list</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">x3</span><span class="special">);</span>
3796	<span class="keyword">return</span> <span class="identifier">op8</span><span class="special">;</span>
3797<span class="special">}</span>
3798</pre>
3799<p>
3800        </p>
3801<p>
3802          I have a <span class="bold"><strong>lot</strong></span> of trouble understanding
3803          what's going on here, and even more verifying that the expression written
3804          in the comment is actually what the code produces. Let's see if we can
3805          do better.
3806        </p>
3807<p>
3808          First, we start with a custom expression template, <code class="computeroutput"><span class="identifier">autodiff_expr</span></code>.
3809          It supports simple arithmetic, but notice it has no call operator —
3810          we don't want <code class="computeroutput"><span class="special">(</span><span class="identifier">a</span>
3811          <span class="special">+</span> <span class="identifier">b</span><span class="special">)()</span></code> to be a valid expression.
3812        </p>
3813<p>
3814</p>
3815<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
3816<span class="keyword">struct</span> <span class="identifier">autodiff_expr</span>
3817<span class="special">{</span>
3818    <span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="keyword">const</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
3819
3820    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
3821<span class="special">};</span>
3822
3823<span class="identifier">BOOST_YAP_USER_UNARY_OPERATOR</span><span class="special">(</span><span class="identifier">negate</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">)</span>
3824
3825<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">plus</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">)</span>
3826<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">minus</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">)</span>
3827<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">)</span>
3828<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">divides</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">,</span> <span class="identifier">autodiff_expr</span><span class="special">)</span>
3829</pre>
3830<p>
3831        </p>
3832<p>
3833          We're going to be using a lot of placeholders in our Autodiff expressions,
3834          and it sure would be nice if they were <code class="computeroutput"><span class="identifier">autodiff_expr</span></code>s
3835          and not <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;s</a></code>, so that only our
3836          desired operators are in play. To do this, we define an operator that produces
3837          placeholder literals, using the <code class="computeroutput"><a class="link" href="../BOOST_YAP__1_3_48_8_2_7_12.html" title="Macro BOOST_YAP_USER_LITERAL_PLACEHOLDER_OPERATOR">BOOST_YAP_USER_LITERAL_PLACEHOLDER_OPERATOR</a></code>
3838          macro:
3839        </p>
3840<p>
3841</p>
3842<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">autodiff_placeholders</span> <span class="special">{</span>
3843
3844    <span class="comment">// This defines a placeholder literal operator that creates autodiff_expr</span>
3845    <span class="comment">// placeholders.</span>
3846    <span class="identifier">BOOST_YAP_USER_LITERAL_PLACEHOLDER_OPERATOR</span><span class="special">(</span><span class="identifier">autodiff_expr</span><span class="special">)</span>
3847
3848<span class="special">}</span>
3849</pre>
3850<p>
3851        </p>
3852<p>
3853          Now, how about the functions we need to support, and where do we put the
3854          call operator? In other examples we created terminal subclasses or templates
3855          to get special behavior on terminals. In this case, we want to create a
3856          function-terminal template:
3857        </p>
3858<p>
3859</p>
3860<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">OPCODE</span> <span class="identifier">Opcode</span><span class="special">&gt;</span>
3861<span class="keyword">struct</span> <span class="identifier">autodiff_fn_expr</span> <span class="special">:</span>
3862    <span class="identifier">autodiff_expr</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">OPCODE</span><span class="special">&gt;&gt;</span>
3863<span class="special">{</span>
3864    <span class="identifier">autodiff_fn_expr</span> <span class="special">()</span> <span class="special">:</span>
3865        <span class="identifier">autodiff_expr</span> <span class="special">{</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">OPCODE</span><span class="special">&gt;{</span><span class="identifier">Opcode</span><span class="special">}}</span>
3866    <span class="special">{}</span>
3867
3868    <span class="identifier">BOOST_YAP_USER_CALL_OPERATOR_N</span><span class="special">(::</span><span class="identifier">autodiff_expr</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
3869<span class="special">};</span>
3870
3871<span class="comment">// Someone included &lt;math.h&gt;, so we have to add trailing underscores.</span>
3872<span class="identifier">autodiff_fn_expr</span><span class="special">&lt;</span><span class="identifier">OP_SIN</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">sin_</span><span class="special">;</span>
3873<span class="identifier">autodiff_fn_expr</span><span class="special">&lt;</span><span class="identifier">OP_COS</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">cos_</span><span class="special">;</span>
3874<span class="identifier">autodiff_fn_expr</span><span class="special">&lt;</span><span class="identifier">OP_SQRT</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">sqrt_</span><span class="special">;</span>
3875</pre>
3876<p>
3877        </p>
3878<p>
3879          <code class="computeroutput"><span class="identifier">OPCODE</span></code> is an enumeration
3880          in Autodiff. We use it as a non-type template parameter for convenience
3881          when declaring <code class="computeroutput"><span class="identifier">sin_</span></code> and
3882          friends. All we really need is for the <code class="computeroutput"><span class="identifier">OPCODE</span></code>
3883          to be the value of the terminals we produce, and for these function-terminals
3884          to have the call operator.
3885        </p>
3886<div class="note"><table border="0" summary="Note">
3887<tr>
3888<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
3889<th align="left">Note</th>
3890</tr>
3891<tr><td align="left" valign="top"><p>
3892            Using <code class="computeroutput"><a class="link" href="../BOOST_YAP_U_1_3_48_8_2_7_5.html" title="Macro BOOST_YAP_USER_CALL_OPERATOR">BOOST_YAP_USER_CALL_OPERATOR</a></code>
3893            is a bit loose here, because it defines a variadic template. We could
3894            have written unary call operators to ensure that the user can't write
3895            call expressions with the wrong number of arguments.
3896          </p></td></tr>
3897</table></div>
3898<p>
3899          Now, some tranforms:
3900        </p>
3901<p>
3902</p>
3903<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">xform</span>
3904<span class="special">{</span>
3905    <span class="comment">// Create a var-node for each placeholder when we see it for the first</span>
3906    <span class="comment">// time.</span>
3907    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">&gt;</span>
3908    <span class="identifier">Node</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
3909                       <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;)</span>
3910    <span class="special">{</span>
3911        <span class="keyword">if</span> <span class="special">(</span><span class="identifier">list_</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">I</span><span class="special">)</span>
3912            <span class="identifier">list_</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="identifier">I</span><span class="special">);</span>
3913        <span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">retval</span> <span class="special">=</span> <span class="identifier">list_</span><span class="special">[</span><span class="identifier">I</span> <span class="special">-</span> <span class="number">1</span><span class="special">];</span>
3914        <span class="keyword">if</span> <span class="special">(</span><span class="identifier">retval</span> <span class="special">==</span> <span class="keyword">nullptr</span><span class="special">)</span>
3915            <span class="identifier">retval</span> <span class="special">=</span> <span class="identifier">create_var_node</span><span class="special">();</span>
3916        <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
3917    <span class="special">}</span>
3918
3919    <span class="comment">// Create a param-node for every numeric terminal in the expression.</span>
3920    <span class="identifier">Node</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span>
3921    <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">create_param_node</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span>
3922
3923    <span class="comment">// Create a "uary" node for each call expression, using its OPCODE.</span>
3924    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
3925    <span class="identifier">Node</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;,</span>
3926                       <span class="identifier">OPCODE</span> <span class="identifier">opcode</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3927    <span class="special">{</span>
3928        <span class="keyword">return</span> <span class="identifier">create_uary_op_node</span><span class="special">(</span>
3929            <span class="identifier">opcode</span><span class="special">,</span>
3930            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">autodiff_expr</span><span class="special">&gt;(</span><span class="identifier">expr</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)</span>
3931        <span class="special">);</span>
3932    <span class="special">}</span>
3933
3934    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
3935    <span class="identifier">Node</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">negate</span><span class="special">&gt;,</span>
3936                       <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
3937    <span class="special">{</span>
3938        <span class="keyword">return</span> <span class="identifier">create_uary_op_node</span><span class="special">(</span>
3939            <span class="identifier">OP_NEG</span><span class="special">,</span>
3940            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">autodiff_expr</span><span class="special">&gt;(</span><span class="identifier">expr</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)</span>
3941        <span class="special">);</span>
3942    <span class="special">}</span>
3943
3944    <span class="comment">// Define a mapping from binary arithmetic expr_kind to OPCODE...</span>
3945    <span class="keyword">static</span> <span class="identifier">OPCODE</span> <span class="identifier">op_for_kind</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">kind</span><span class="special">)</span>
3946    <span class="special">{</span>
3947        <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">kind</span><span class="special">)</span> <span class="special">{</span>
3948        <span class="keyword">case</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">plus</span><span class="special">:</span> <span class="keyword">return</span> <span class="identifier">OP_PLUS</span><span class="special">;</span>
3949        <span class="keyword">case</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">minus</span><span class="special">:</span> <span class="keyword">return</span> <span class="identifier">OP_MINUS</span><span class="special">;</span>
3950        <span class="keyword">case</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special">:</span> <span class="keyword">return</span> <span class="identifier">OP_TIMES</span><span class="special">;</span>
3951        <span class="keyword">case</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">divides</span><span class="special">:</span> <span class="keyword">return</span> <span class="identifier">OP_DIVID</span><span class="special">;</span>
3952        <span class="keyword">default</span><span class="special">:</span> <span class="identifier">assert</span><span class="special">(!</span><span class="string">"This should never execute"</span><span class="special">);</span> <span class="keyword">return</span> <span class="identifier">OPCODE</span><span class="special">{};</span>
3953        <span class="special">}</span>
3954        <span class="identifier">assert</span><span class="special">(!</span><span class="string">"This should never execute"</span><span class="special">);</span>
3955        <span class="keyword">return</span> <span class="identifier">OPCODE</span><span class="special">{};</span>
3956    <span class="special">}</span>
3957
3958    <span class="comment">// ... and use it to handle all the binary arithmetic operators.</span>
3959    <span class="keyword">template</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr2</span><span class="special">&gt;</span>
3960    <span class="identifier">Node</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">Kind</span><span class="special">&gt;,</span> <span class="identifier">Expr1</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr1</span><span class="special">,</span> <span class="identifier">Expr2</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr2</span><span class="special">)</span>
3961    <span class="special">{</span>
3962        <span class="keyword">return</span> <span class="identifier">create_binary_op_node</span><span class="special">(</span>
3963            <span class="identifier">op_for_kind</span><span class="special">(</span><span class="identifier">Kind</span><span class="special">),</span>
3964            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">autodiff_expr</span><span class="special">&gt;(</span><span class="identifier">expr1</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">),</span>
3965            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">&lt;</span><span class="identifier">autodiff_expr</span><span class="special">&gt;(</span><span class="identifier">expr2</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)</span>
3966        <span class="special">);</span>
3967    <span class="special">}</span>
3968
3969    <span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Node</span> <span class="special">*&gt;</span> <span class="special">&amp;</span> <span class="identifier">list_</span><span class="special">;</span>
3970<span class="special">};</span>
3971</pre>
3972<p>
3973        </p>
3974<p>
3975          We need a function to tie everything together, since the transforms cannot
3976          fill in the values for the placeholders.
3977        </p>
3978<p>
3979</p>
3980<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span><span class="identifier">T</span><span class="special">&gt;</span>
3981<span class="identifier">Node</span> <span class="special">*</span> <span class="identifier">to_auto_diff_node</span> <span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Node</span> <span class="special">*&gt;</span> <span class="special">&amp;</span> <span class="identifier">list</span><span class="special">,</span> <span class="identifier">T</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">)</span>
3982<span class="special">{</span>
3983    <span class="identifier">Node</span> <span class="special">*</span> <span class="identifier">retval</span> <span class="special">=</span> <span class="keyword">nullptr</span><span class="special">;</span>
3984
3985    <span class="comment">// This fills in list as a side effect.</span>
3986    <span class="identifier">retval</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">xform</span><span class="special">{</span><span class="identifier">list</span><span class="special">});</span>
3987
3988    <span class="identifier">assert</span><span class="special">(</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">args</span><span class="special">));</span>
3989
3990    <span class="comment">// Fill in the values of the value-nodes in list with the "args"</span>
3991    <span class="comment">// parameter pack.</span>
3992    <span class="keyword">auto</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">list</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
3993    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span>
3994        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">args</span> <span class="special">...),</span>
3995        <span class="special">[&amp;</span><span class="identifier">it</span><span class="special">](</span><span class="keyword">auto</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>
3996            <span class="identifier">Node</span> <span class="special">*</span> <span class="identifier">n</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span>
3997            <span class="identifier">VNode</span> <span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">polymorphic_downcast</span><span class="special">&lt;</span><span class="identifier">VNode</span> <span class="special">*&gt;(</span><span class="identifier">n</span><span class="special">);</span>
3998            <span class="identifier">v</span><span class="special">-&gt;</span><span class="identifier">val</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">;</span>
3999            <span class="special">++</span><span class="identifier">it</span><span class="special">;</span>
4000        <span class="special">}</span>
4001    <span class="special">);</span>
4002
4003    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
4004<span class="special">}</span>
4005</pre>
4006<p>
4007        </p>
4008<p>
4009          Finally, here is the Boost.YAP version of the function we started with:
4010        </p>
4011<p>
4012</p>
4013<pre class="programlisting"><span class="identifier">Node</span><span class="special">*</span> <span class="identifier">build_linear_fun1</span><span class="special">(</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Node</span><span class="special">*&gt;&amp;</span> <span class="identifier">list</span><span class="special">)</span>
4014<span class="special">{</span>
4015    <span class="comment">//f(x1,x2,x3) = -5*x1+sin(10)*x1+10*x2-x3/6</span>
4016    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">autodiff_placeholders</span><span class="special">;</span>
4017    <span class="keyword">return</span> <span class="identifier">to_auto_diff_node</span><span class="special">(</span>
4018        <span class="special">-</span><span class="number">5</span> <span class="special">*</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">+</span> <span class="identifier">sin_</span><span class="special">(</span><span class="number">10</span><span class="special">)</span> <span class="special">*</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">+</span> <span class="number">10</span> <span class="special">*</span> <span class="number">2</span><span class="identifier">_p</span> <span class="special">-</span> <span class="number">3</span><span class="identifier">_p</span> <span class="special">/</span> <span class="number">6</span><span class="special">,</span>
4019        <span class="identifier">list</span><span class="special">,</span>
4020        <span class="special">-</span><span class="number">1.9</span><span class="special">,</span>
4021        <span class="number">2</span><span class="special">,</span>
4022        <span class="number">5.</span><span class="special">/</span><span class="number">6.</span>
4023    <span class="special">);</span>
4024<span class="special">}</span>
4025</pre>
4026<p>
4027        </p>
4028</div>
4029<div class="section">
4030<div class="titlepage"><div><div><h4 class="title">
4031<a name="boost_yap.manual.examples.transforming_terminals_only"></a><a class="link" href="manual.html#boost_yap.manual.examples.transforming_terminals_only" title="Transforming Terminals Only">Transforming
4032        Terminals Only</a>
4033</h4></div></div></div>
4034<p>
4035          Sometimes it can be useful only to transform the terminals in an expression.
4036          For instance, if you have some type you use for SIMD operations called
4037          <code class="computeroutput"><span class="identifier">simd</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>,
4038          you may want to replace all the <code class="computeroutput"><span class="keyword">double</span></code>
4039          terminals with <code class="computeroutput"><span class="identifier">simd</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span></code>.
4040          Perhaps you just want to change out <code class="computeroutput"><span class="keyword">double</span></code>
4041          for <code class="computeroutput"><span class="keyword">float</span></code>, or <code class="computeroutput"><span class="keyword">int</span></code> for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>.
4042          You get the idea.
4043        </p>
4044<p>
4045          In this example, we're replacing all the terminals with something essentially
4046          arbitrary, the sequence of integer terminals <code class="computeroutput"><span class="identifier">N</span><span class="special">,</span> <span class="identifier">N</span> <span class="special">+</span> <span class="number">1</span><span class="special">,</span>
4047          <span class="identifier">N</span> <span class="special">+</span>
4048          <span class="number">2</span><span class="special">,</span> <span class="special">...</span></code>. This makes it easier to observe the
4049          result of the replacement in a simple example.
4050        </p>
4051<p>
4052</p>
4053<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4054
4055
4056<span class="keyword">struct</span> <span class="identifier">iota_terminal_transform</span>
4057<span class="special">{</span>
4058    <span class="comment">// Base case. Note that we're not treating placeholders specially for this</span>
4059    <span class="comment">// example (they're easy to special-case if necessary).</span>
4060    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
4061    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span> <span class="identifier">T</span> <span class="special">&amp;&amp;</span> <span class="identifier">t</span><span class="special">)</span>
4062    <span class="special">{</span>
4063        <span class="comment">// Like the std::iota() algorithm, we create replacement int terminals</span>
4064        <span class="comment">// with the values index_, index_ + 1, index_ + 2, etc.</span>
4065        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">index_</span><span class="special">++);</span>
4066    <span class="special">}</span>
4067
4068    <span class="comment">// Recursive case: Match any call expression.</span>
4069    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">CallableExpr</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Arg</span><span class="special">&gt;</span>
4070    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;,</span>
4071                    <span class="identifier">CallableExpr</span> <span class="identifier">callable</span><span class="special">,</span> <span class="identifier">Arg</span> <span class="special">&amp;&amp;...</span> <span class="identifier">arg</span><span class="special">)</span>
4072    <span class="special">{</span>
4073        <span class="comment">// Even though the callable in a call expression is technically a</span>
4074        <span class="comment">// terminal, it doesn't make a lot of sense to replace it with an int,</span>
4075        <span class="comment">// so we'll only transform the argument subexpressions.</span>
4076        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_expression</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;(</span>
4077            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">callable</span><span class="special">),</span>
4078            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">as_expr</span><span class="special">(</span><span class="identifier">arg</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">)...);</span>
4079    <span class="special">}</span>
4080
4081    <span class="keyword">int</span> <span class="identifier">index_</span><span class="special">;</span>
4082<span class="special">};</span>
4083
4084<span class="keyword">int</span> <span class="identifier">sum</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">a</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">a</span> <span class="special">+</span> <span class="identifier">b</span><span class="special">;</span> <span class="special">}</span>
4085
4086<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
4087<span class="special">{</span>
4088    <span class="special">{</span>
4089        <span class="comment">// This simple sum(8, 8) expression requires both overloads of</span>
4090        <span class="comment">// iota_terminal_transform.</span>
4091        <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">sum</span><span class="special">)(</span><span class="number">8</span><span class="special">,</span> <span class="number">8</span><span class="special">);</span>
4092        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special">==</span> <span class="number">16</span><span class="special">);</span>
4093
4094        <span class="keyword">auto</span> <span class="identifier">iota_expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">iota_terminal_transform</span><span class="special">{</span><span class="number">1</span><span class="special">});</span>
4095        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">iota_expr</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
4096    <span class="special">}</span>
4097
4098    <span class="special">{</span>
4099        <span class="comment">// This expression requires only the terminal case of</span>
4100        <span class="comment">// iota_terminal_transform.</span>
4101        <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="special">-(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="number">8</span><span class="special">)</span> <span class="special">+</span> <span class="number">8</span><span class="special">);</span>
4102        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">16</span><span class="special">);</span>
4103
4104        <span class="keyword">auto</span> <span class="identifier">iota_expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">iota_terminal_transform</span><span class="special">{</span><span class="number">0</span><span class="special">});</span>
4105        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">iota_expr</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>
4106    <span class="special">}</span>
4107
4108    <span class="special">{</span>
4109        <span class="comment">// Like the first expression above, this expression requires both</span>
4110        <span class="comment">// overloads of iota_terminal_transform.</span>
4111        <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">sum</span><span class="special">)(-(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="number">8</span><span class="special">)</span> <span class="special">+</span> <span class="number">8</span><span class="special">),</span> <span class="number">0</span><span class="special">);</span>
4112        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">16</span><span class="special">);</span>
4113
4114        <span class="keyword">auto</span> <span class="identifier">iota_expr</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">iota_terminal_transform</span><span class="special">{</span><span class="number">0</span><span class="special">});</span>
4115        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">iota_expr</span><span class="special">)</span> <span class="special">==</span> <span class="special">-</span><span class="number">3</span><span class="special">);</span>
4116    <span class="special">}</span>
4117<span class="special">}</span>
4118</pre>
4119<p>
4120        </p>
4121</div>
4122<div class="section">
4123<div class="titlepage"><div><div><h4 class="title">
4124<a name="boost_yap.manual.examples.pipable_algorithms"></a><a class="link" href="manual.html#boost_yap.manual.examples.pipable_algorithms" title="Pipable Algorithms">Pipable
4125        Algorithms</a>
4126</h4></div></div></div>
4127<p>
4128          Let's revisit the pipable standard algorithm example from the intro. Here's
4129          how you might implement it.
4130        </p>
4131<p>
4132</p>
4133<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4134
4135<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
4136<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
4137
4138
4139<span class="comment">// An enum to represent all the standard algorithms we want to adapt.  In this</span>
4140<span class="comment">// example, we only care about std::sort() and std::unique().</span>
4141<span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">algorithm_t</span> <span class="special">{</span> <span class="identifier">sort</span><span class="special">,</span> <span class="identifier">unique</span> <span class="special">};</span>
4142
4143<span class="comment">// Just about the simplest range template you could construct.  Nothing fancy.</span>
4144<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">&gt;</span>
4145<span class="keyword">struct</span> <span class="identifier">simple_range</span>
4146<span class="special">{</span>
4147    <span class="identifier">Iter</span> <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">first_</span><span class="special">;</span> <span class="special">}</span>
4148    <span class="identifier">Iter</span> <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">last_</span><span class="special">;</span> <span class="special">}</span>
4149
4150    <span class="identifier">Iter</span> <span class="identifier">first_</span><span class="special">;</span>
4151    <span class="identifier">Iter</span> <span class="identifier">last_</span><span class="special">;</span>
4152<span class="special">};</span>
4153
4154<span class="comment">// This simply calls the standard algorithm that corresponds to "a".  This</span>
4155<span class="comment">// certainly won't work for all the algorithms, but it works for many of them</span>
4156<span class="comment">// that just take a begin/end pair.</span>
4157<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">&gt;</span>
4158<span class="keyword">auto</span> <span class="identifier">call_algorithm</span><span class="special">(</span><span class="identifier">algorithm_t</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Range</span> <span class="special">&amp;</span> <span class="identifier">r</span><span class="special">)</span>
4159<span class="special">{</span>
4160    <span class="identifier">simple_range</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())&gt;</span> <span class="identifier">retval</span><span class="special">{</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">end</span><span class="special">()};</span>
4161    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">==</span> <span class="identifier">algorithm_t</span><span class="special">::</span><span class="identifier">sort</span><span class="special">)</span> <span class="special">{</span>
4162        <span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
4163    <span class="special">}</span> <span class="keyword">else</span> <span class="keyword">if</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">==</span> <span class="identifier">algorithm_t</span><span class="special">::</span><span class="identifier">unique</span><span class="special">)</span> <span class="special">{</span>
4164        <span class="identifier">retval</span><span class="special">.</span><span class="identifier">last_</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique</span><span class="special">(</span><span class="identifier">r</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
4165    <span class="special">}</span>
4166    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
4167<span class="special">}</span>
4168
4169<span class="comment">// This is the transform that evaluates our piped expressions.  It returns a</span>
4170<span class="comment">// simple_range&lt;&gt;, not a Yap expression.</span>
4171<span class="keyword">struct</span> <span class="identifier">algorithm_eval</span>
4172<span class="special">{</span>
4173    <span class="comment">// A pipe should always have a Yap expression on the left and an</span>
4174    <span class="comment">// algorithm_t terminal on the right.</span>
4175    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">LExpr</span><span class="special">&gt;</span>
4176    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span>
4177        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">bitwise_or</span><span class="special">&gt;,</span>
4178        <span class="identifier">LExpr</span> <span class="special">&amp;&amp;</span> <span class="identifier">left</span><span class="special">,</span>
4179        <span class="identifier">algorithm_t</span> <span class="identifier">right</span><span class="special">)</span>
4180    <span class="special">{</span>
4181        <span class="comment">// Recursively evaluate the left ...</span>
4182        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">left_result</span> <span class="special">=</span>
4183            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">LExpr</span><span class="special">&gt;(</span><span class="identifier">left</span><span class="special">),</span> <span class="special">*</span><span class="keyword">this</span><span class="special">);</span>
4184        <span class="comment">// ... and use the result to call the function on the right.</span>
4185        <span class="keyword">return</span> <span class="identifier">call_algorithm</span><span class="special">(</span><span class="identifier">right</span><span class="special">,</span> <span class="identifier">left_result</span><span class="special">);</span>
4186    <span class="special">}</span>
4187
4188    <span class="comment">// A call operation is evaluated directly.  Note that the range parameter</span>
4189    <span class="comment">// is taken as an lvalue reference, to prevent binding to a temporary and</span>
4190    <span class="comment">// taking dangling references to its begin and end.  We let the compiler</span>
4191    <span class="comment">// deduce whether the lvalue reference is const.</span>
4192    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">&gt;</span>
4193    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span>
4194        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">&gt;,</span>
4195        <span class="identifier">algorithm_t</span> <span class="identifier">a</span><span class="special">,</span>
4196        <span class="identifier">Range</span> <span class="special">&amp;</span> <span class="identifier">r</span><span class="special">)</span>
4197    <span class="special">{</span>
4198        <span class="keyword">return</span> <span class="identifier">call_algorithm</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">r</span><span class="special">);</span>
4199    <span class="special">}</span>
4200<span class="special">};</span>
4201
4202<span class="comment">// This is the expression template we use for the general case of a pipable</span>
4203<span class="comment">// algorithm expression.  Terminals are handled separately.</span>
4204<span class="keyword">template</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="identifier">Kind</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">&gt;</span>
4205<span class="keyword">struct</span> <span class="identifier">algorithm_expr</span>
4206<span class="special">{</span>
4207    <span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="keyword">const</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">Kind</span><span class="special">;</span>
4208
4209    <span class="identifier">Tuple</span> <span class="identifier">elements</span><span class="special">;</span>
4210
4211    <span class="comment">// This is how we get the nice initializer semantics we see in the example</span>
4212    <span class="comment">// usage below.  This is a bit limited though, because we always create a</span>
4213    <span class="comment">// temporary.  It might therefore be better just to create algorithm_expr</span>
4214    <span class="comment">// expressions, call yap::evaluate(), and then use the sequence containers</span>
4215    <span class="comment">// assign() member function to do the actual assignment.</span>
4216    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Assignee</span><span class="special">&gt;</span>
4217    <span class="keyword">operator</span> <span class="identifier">Assignee</span><span class="special">()</span> <span class="keyword">const</span>
4218    <span class="special">{</span>
4219        <span class="comment">// Exercise left for the reader: static_assert() that Assignee is some</span>
4220        <span class="comment">// sort of container type.</span>
4221        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">range</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">algorithm_eval</span><span class="special">{});</span>
4222        <span class="keyword">return</span> <span class="identifier">Assignee</span><span class="special">(</span><span class="identifier">range</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">range</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
4223    <span class="special">}</span>
4224<span class="special">};</span>
4225
4226
4227<span class="comment">// This is a bit loose, because it allows us to write "sort(v) | unique(u)" or</span>
4228<span class="comment">// similar.  It works fine for this example, but in production code you may</span>
4229<span class="comment">// want to write out the functions generated by this macro, and add SFINAE or</span>
4230<span class="comment">// concepts constraints on the right template parameter.</span>
4231<span class="identifier">BOOST_YAP_USER_BINARY_OPERATOR</span><span class="special">(</span><span class="identifier">bitwise_or</span><span class="special">,</span> <span class="identifier">algorithm_expr</span><span class="special">,</span> <span class="identifier">algorithm_expr</span><span class="special">)</span>
4232
4233<span class="comment">// It's useful to specially handle terminals, because we want a different set</span>
4234<span class="comment">// of operations to apply to them.  We don't want "sort(x)(y)" to be</span>
4235<span class="comment">// well-formed, for instance, or "sort | unique" either.</span>
4236<span class="keyword">struct</span> <span class="identifier">algorithm</span>
4237<span class="special">{</span>
4238    <span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span> <span class="keyword">const</span> <span class="identifier">kind</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">;</span>
4239
4240    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">algorithm_t</span><span class="special">&gt;</span> <span class="identifier">elements</span><span class="special">;</span>
4241
4242    <span class="identifier">BOOST_YAP_USER_CALL_OPERATOR_N</span><span class="special">(::</span><span class="identifier">algorithm_expr</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span>
4243<span class="special">};</span>
4244
4245<span class="comment">// Here are ready-made Yap terminals, one for each algorithm enumerated in</span>
4246<span class="comment">// algorithm_t.</span>
4247<span class="keyword">constexpr</span> <span class="identifier">algorithm</span> <span class="identifier">sort</span><span class="special">{{</span><span class="identifier">algorithm_t</span><span class="special">::</span><span class="identifier">sort</span><span class="special">}};</span>
4248<span class="keyword">constexpr</span> <span class="identifier">algorithm</span> <span class="identifier">unique</span><span class="special">{{</span><span class="identifier">algorithm_t</span><span class="special">::</span><span class="identifier">unique</span><span class="special">}};</span>
4249
4250<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
4251<span class="special">{</span>
4252    <span class="special">{</span>
4253        <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="special">{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">8</span><span class="special">};</span>
4254        <span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="identifier">v1</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
4255        <span class="keyword">auto</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique</span><span class="special">(</span><span class="identifier">v1</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v1</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
4256        <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">v2</span><span class="special">(</span><span class="identifier">v1</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">it</span><span class="special">);</span>
4257        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v2</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;({</span><span class="number">0</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">7</span><span class="special">,</span> <span class="number">8</span><span class="special">}));</span>
4258    <span class="special">}</span>
4259    <span class="special">{</span>
4260        <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v1</span> <span class="special">=</span> <span class="special">{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">8</span><span class="special">};</span>
4261        <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">v2</span> <span class="special">=</span> <span class="identifier">sort</span><span class="special">(</span><span class="identifier">v1</span><span class="special">)</span> <span class="special">|</span> <span class="identifier">unique</span><span class="special">;</span>
4262        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">v2</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;({</span><span class="number">0</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">7</span><span class="special">,</span> <span class="number">8</span><span class="special">}));</span>
4263    <span class="special">}</span>
4264<span class="special">}</span>
4265</pre>
4266<p>
4267        </p>
4268</div>
4269<div class="section">
4270<div class="titlepage"><div><div><h4 class="title">
4271<a name="boost_yap.manual.examples.boost_phoenix_style__let___"></a><a class="link" href="manual.html#boost_yap.manual.examples.boost_phoenix_style__let___" title="Boost.Phoenix-style let()">Boost.Phoenix-style
4272        <code class="computeroutput"><span class="identifier">let</span><span class="special">()</span></code></a>
4273</h4></div></div></div>
4274<p>
4275          Boost.Phoenix has a thing called <a href="http://www.boost.org/doc/libs/1_66_0/libs/phoenix/doc/html/phoenix/modules/scope/let.html" target="_top"><code class="computeroutput"><span class="identifier">let</span><span class="special">()</span></code></a>.
4276          It introduces named reusable values that are usable in subsequent expressions.
4277          This example is something simliar, though not exactly like Phoenix's version.
4278          In Phoenix, a let placeholder is only evaluated once, whereas the example
4279          below does something more like macro substitution; each let-placeholder
4280          is replaced with its initializing expression everywhere it is used.
4281        </p>
4282<p>
4283          This example uses C++17's <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">()</span></code>,
4284          simply because it makes the example shorter and easier to digest. The
4285          <code class="computeroutput"><span class="keyword">if</span> <span class="keyword">constexpr</span>
4286          <span class="special">()</span></code> bits are not strictly necessary.
4287        </p>
4288<p>
4289</p>
4290<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4291
4292<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4293<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">at_key</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4294<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">contains</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4295<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">hana</span><span class="special">/</span><span class="identifier">keys</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4296
4297<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
4298<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
4299
4300
4301<span class="comment">// Here, we introduce special let-placeholders, so we can use them along side</span>
4302<span class="comment">// the normal YAP placeholders without getting them confused.</span>
4303<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">&gt;</span>
4304<span class="keyword">struct</span> <span class="identifier">let_placeholder</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span>
4305<span class="special">{</span>
4306<span class="special">};</span>
4307
4308<span class="comment">// Replaces each let-terminal with the expression with which it was</span>
4309<span class="comment">// initialized in let().  So in 'let(_a = foo)[ _a + 1 ]', this transform will</span>
4310<span class="comment">// be used on '_a + 1' to replace '_a' with 'foo'.  The map_ member holds the</span>
4311<span class="comment">// mapping of let-placeholders to their initializers.</span>
4312<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">ExprMap</span><span class="special">&gt;</span>
4313<span class="keyword">struct</span> <span class="identifier">let_terminal_transform</span>
4314<span class="special">{</span>
4315    <span class="comment">// This matches only let-placeholders.  For each one matched, we look up</span>
4316    <span class="comment">// its initializer in map_ and return it.</span>
4317    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">&gt;</span>
4318    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">()(</span>
4319        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_tag</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&gt;,</span>
4320        <span class="identifier">let_placeholder</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;</span> <span class="identifier">i</span><span class="special">)</span>
4321    <span class="special">{</span>
4322        <span class="comment">// If we have an entry in map_ for this placeholder, return the value</span>
4323        <span class="comment">// of the entry.  Otherwise, pass i through as a terminal.</span>
4324        <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">contains</span><span class="special">(</span>
4325                          <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">keys</span><span class="special">(</span><span class="identifier">map_</span><span class="special">))(),</span>
4326                          <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;))</span> <span class="special">{</span>
4327            <span class="keyword">return</span> <span class="identifier">map_</span><span class="special">[</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;];</span>
4328        <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
4329            <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
4330        <span class="special">}</span>
4331    <span class="special">}</span>
4332
4333    <span class="identifier">ExprMap</span> <span class="identifier">map_</span><span class="special">;</span>
4334<span class="special">};</span>
4335
4336<span class="comment">// As you can see below, let() is an eager function; this template is used for</span>
4337<span class="comment">// its return values.  It contains the mapping from let-placeholders to</span>
4338<span class="comment">// initializer expressions used to transform the expression inside '[]' after</span>
4339<span class="comment">// a let()'.  It also has an operator[]() member function that takes the</span>
4340<span class="comment">// expression inside '[]' and returns a version of it with the</span>
4341<span class="comment">// let-placeholders replaced.</span>
4342<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">ExprMap</span><span class="special">&gt;</span>
4343<span class="keyword">struct</span> <span class="identifier">let_result</span>
4344<span class="special">{</span>
4345    <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span>
4346    <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">Expr</span> <span class="special">&amp;&amp;</span> <span class="identifier">expr</span><span class="special">)</span>
4347    <span class="special">{</span>
4348        <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span>
4349            <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">let_terminal_transform</span><span class="special">&lt;</span><span class="identifier">ExprMap</span><span class="special">&gt;{</span><span class="identifier">map_</span><span class="special">});</span>
4350    <span class="special">}</span>
4351
4352    <span class="identifier">ExprMap</span> <span class="identifier">map_</span><span class="special">;</span>
4353<span class="special">};</span>
4354
4355<span class="comment">// Processes the expressions passed to let() one at a time, adding each one to</span>
4356<span class="comment">// a Hana map of hana::llong&lt;&gt;s to YAP expressions.</span>
4357<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Map</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="special">...</span> <span class="identifier">Exprs</span><span class="special">&gt;</span>
4358<span class="keyword">auto</span> <span class="identifier">let_impl</span><span class="special">(</span><span class="identifier">Map</span> <span class="special">&amp;&amp;</span> <span class="identifier">map</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="special">&amp;&amp;</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Exprs</span> <span class="special">&amp;&amp;...</span> <span class="identifier">exprs</span><span class="special">)</span>
4359<span class="special">{</span>
4360    <span class="keyword">static_assert</span><span class="special">(</span>
4361        <span class="identifier">Expr</span><span class="special">::</span><span class="identifier">kind</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">assign</span><span class="special">,</span>
4362        <span class="string">"Expressions passed to let() must be of the form placeholder = Expression"</span><span class="special">);</span>
4363    <span class="keyword">if</span> <span class="keyword">constexpr</span> <span class="special">(</span><span class="keyword">sizeof</span><span class="special">...(</span><span class="identifier">Exprs</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
4364        <span class="keyword">using</span> <span class="identifier">I</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span>
4365            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">left</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)))&gt;::</span><span class="identifier">type</span><span class="special">;</span>
4366        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">::</span><span class="identifier">value</span><span class="special">&gt;;</span>
4367        <span class="keyword">using</span> <span class="identifier">map_t</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">insert</span><span class="special">(</span>
4368            <span class="identifier">map</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">expr</span><span class="special">))));</span>
4369        <span class="keyword">return</span> <span class="identifier">let_result</span><span class="special">&lt;</span><span class="identifier">map_t</span><span class="special">&gt;{</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">insert</span><span class="special">(</span>
4370            <span class="identifier">map</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)))};</span>
4371    <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
4372        <span class="keyword">using</span> <span class="identifier">I</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span>
4373            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">left</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)))&gt;::</span><span class="identifier">type</span><span class="special">;</span>
4374        <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">llong_c</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">::</span><span class="identifier">value</span><span class="special">&gt;;</span>
4375        <span class="keyword">return</span> <span class="identifier">let_impl</span><span class="special">(</span>
4376            <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">insert</span><span class="special">(</span>
4377                <span class="identifier">map</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">right</span><span class="special">(</span><span class="identifier">expr</span><span class="special">))),</span>
4378            <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Exprs</span><span class="special">&gt;(</span><span class="identifier">exprs</span><span class="special">)...);</span>
4379    <span class="special">}</span>
4380<span class="special">}</span>
4381
4382<span class="comment">// Takes N &gt; 0 expressions of the form 'placeholder = expr', and returns an</span>
4383<span class="comment">// object with an overloaded operator[]().</span>
4384<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Exprs</span><span class="special">&gt;</span>
4385<span class="keyword">auto</span> <span class="identifier">let</span><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&amp;&amp;</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Exprs</span> <span class="special">&amp;&amp;...</span> <span class="identifier">exprs</span><span class="special">)</span>
4386<span class="special">{</span>
4387    <span class="keyword">return</span> <span class="identifier">let_impl</span><span class="special">(</span>
4388        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">make_map</span><span class="special">(),</span>
4389        <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;(</span><span class="identifier">expr</span><span class="special">),</span>
4390        <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Exprs</span><span class="special">&gt;(</span><span class="identifier">exprs</span><span class="special">)...);</span>
4391<span class="special">}</span>
4392
4393<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
4394<span class="special">{</span>
4395    <span class="comment">// Some handy terminals -- the _a and _b let-placeholders and std::cout as</span>
4396    <span class="comment">// a YAP terminal.</span>
4397    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
4398        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
4399        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">let_placeholder</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;&gt;&gt;</span> <span class="keyword">const</span> <span class="identifier">_a</span><span class="special">;</span>
4400    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expression</span><span class="special">&lt;</span>
4401        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span>
4402        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">let_placeholder</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;&gt;&gt;</span> <span class="keyword">const</span> <span class="identifier">_b</span><span class="special">;</span>
4403    <span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">cout</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">make_terminal</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">);</span>
4404
4405    <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">literals</span><span class="special">;</span>
4406
4407    <span class="special">{</span>
4408        <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">let</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="number">2</span><span class="special">)[</span><span class="identifier">_a</span> <span class="special">+</span> <span class="number">1</span><span class="special">];</span>
4409        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
4410    <span class="special">}</span>
4411
4412    <span class="special">{</span>
4413        <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">let</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="number">123</span><span class="special">,</span> <span class="identifier">_b</span> <span class="special">=</span> <span class="number">456</span><span class="special">)[</span><span class="identifier">_a</span> <span class="special">+</span> <span class="identifier">_b</span><span class="special">];</span>
4414        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special">==</span> <span class="number">123</span> <span class="special">+</span> <span class="number">456</span><span class="special">);</span>
4415    <span class="special">}</span>
4416
4417    <span class="comment">// This prints out "0 0", because 'i' is passed as an lvalue, so its</span>
4418    <span class="comment">// decrement is visible outside the let expression.</span>
4419    <span class="special">{</span>
4420        <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
4421
4422        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">let</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span><span class="special">)[</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">--</span><span class="identifier">_a</span> <span class="special">&lt;&lt;</span> <span class="char">' '</span><span class="special">],</span> <span class="identifier">i</span><span class="special">);</span>
4423
4424        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
4425    <span class="special">}</span>
4426
4427    <span class="comment">// Prints "Hello, World" due to let()'s scoping rules.</span>
4428    <span class="special">{</span>
4429        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span>
4430            <span class="identifier">let</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span><span class="special">,</span> <span class="identifier">_b</span> <span class="special">=</span> <span class="number">2</span><span class="identifier">_p</span><span class="special">)</span>
4431            <span class="special">[</span>
4432                <span class="comment">// _a here is an int: 1</span>
4433
4434                <span class="identifier">let</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="number">3</span><span class="identifier">_p</span><span class="special">)</span> <span class="comment">// hides the outer _a</span>
4435                <span class="special">[</span>
4436                    <span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">_a</span> <span class="special">&lt;&lt;</span> <span class="identifier">_b</span> <span class="comment">// prints "Hello, World"</span>
4437                <span class="special">]</span>
4438            <span class="special">],</span>
4439            <span class="number">1</span><span class="special">,</span> <span class="string">" World"</span><span class="special">,</span> <span class="string">"Hello,"</span>
4440        <span class="special">);</span>
4441    <span class="special">}</span>
4442
4443    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
4444
4445    <span class="comment">// Due to the macro-substitution style that this example uses, this prints</span>
4446    <span class="comment">// "3132".  Phoenix's let() prints "312", because it only evaluates '1_p</span>
4447    <span class="comment">// &lt;&lt; 3' once.</span>
4448    <span class="special">{</span>
4449        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span>
4450            <span class="identifier">let</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="number">1</span><span class="identifier">_p</span> <span class="special">&lt;&lt;</span> <span class="number">3</span><span class="special">)</span>
4451            <span class="special">[</span>
4452                <span class="identifier">_a</span> <span class="special">&lt;&lt;</span> <span class="string">"1"</span><span class="special">,</span> <span class="identifier">_a</span> <span class="special">&lt;&lt;</span> <span class="string">"2"</span>
4453            <span class="special">],</span>
4454            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span>
4455        <span class="special">);</span>
4456    <span class="special">}</span>
4457
4458    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
4459<span class="special">}</span>
4460</pre>
4461<p>
4462        </p>
4463</div>
4464</div>
4465<div class="section">
4466<div class="titlepage"><div><div><h3 class="title">
4467<a name="boost_yap.manual.header_organization"></a><a class="link" href="manual.html#boost_yap.manual.header_organization" title="Header Organization">Header Organization</a>
4468</h3></div></div></div>
4469<p>
4470        The main header you will always need to use Boost.YAP is the <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
4471        header. If you want to ensure that you don't accidentally use <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code> (which I recommend),
4472        just include this header and nothing else.
4473      </p>
4474<p>
4475        If you want to use the <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression&lt;&gt;</a></code>
4476        reference expression template (great for prototyping, but not recommended
4477        for production work), include the <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
4478        header.
4479      </p>
4480<p>
4481        If you want to include all of the above, use the <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
4482        header.
4483      </p>
4484<p>
4485        If you want to use <code class="computeroutput"><a class="link" href="../boost/yap/print.html" title="Function template print">print()</a></code>, include the <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">print</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
4486        header; this header is not included in the <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">yap</span><span class="special">/</span><span class="identifier">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
4487        header.
4488      </p>
4489</div>
4490<div class="section">
4491<div class="titlepage"><div><div><h3 class="title">
4492<a name="boost_yap.manual.configuration"></a><a class="link" href="manual.html#boost_yap.manual.configuration" title="Configuration">Configuration</a>
4493</h3></div></div></div>
4494<p>
4495        <code class="computeroutput"><a class="link" href="../BOOST_NO_CONSTEXPR_IF.html" title="Macro BOOST_NO_CONSTEXPR_IF">BOOST_NO_CONSTEXPR_IF</a></code>
4496        is a macro that indicates whether the compiler has support for constexpr
4497        if. It defaults to no. Define it to be a nonzero value if your compiler has
4498        constexpr if support. Note that this is a temporary hack; this should eventually
4499        be a Boost-wide macro.
4500      </p>
4501</div>
4502<div class="section">
4503<div class="titlepage"><div><div><h3 class="title">
4504<a name="boost_yap.manual.object_code"></a><a class="link" href="manual.html#boost_yap.manual.object_code" title="Object Code">Object Code</a>
4505</h3></div></div></div>
4506<p>
4507        Let's look at some assembly. All assembly here was produced with Clang 4.0
4508        with <code class="computeroutput"><span class="special">-</span><span class="identifier">O3</span></code>.
4509        Given these definitions:
4510      </p>
4511<p>
4512</p>
4513<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">user</span> <span class="special">{</span>
4514
4515    <span class="keyword">struct</span> <span class="identifier">number</span>
4516    <span class="special">{</span>
4517        <span class="keyword">double</span> <span class="identifier">value</span><span class="special">;</span>
4518
4519        <span class="keyword">friend</span> <span class="identifier">number</span> <span class="keyword">operator</span><span class="special">+(</span><span class="identifier">number</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">number</span> <span class="identifier">rhs</span><span class="special">)</span>
4520        <span class="special">{</span>
4521            <span class="keyword">return</span> <span class="identifier">number</span><span class="special">{</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">value</span> <span class="special">+</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">value</span><span class="special">};</span>
4522        <span class="special">}</span>
4523
4524        <span class="keyword">friend</span> <span class="identifier">number</span> <span class="keyword">operator</span><span class="special">*(</span><span class="identifier">number</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">number</span> <span class="identifier">rhs</span><span class="special">)</span>
4525        <span class="special">{</span>
4526            <span class="keyword">return</span> <span class="identifier">number</span><span class="special">{</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">value</span> <span class="special">*</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">value</span><span class="special">};</span>
4527        <span class="special">}</span>
4528    <span class="special">};</span>
4529<span class="special">}</span>
4530</pre>
4531<p>
4532      </p>
4533<p>
4534        Here is a Boost.YAP-based arithmetic function:
4535      </p>
4536<p>
4537</p>
4538<pre class="programlisting"><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">eval_as_yap_expr</span><span class="special">(</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">a_</span><span class="special">,</span> <span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">x_</span><span class="special">,</span> <span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">y_</span><span class="special">)</span>
4539<span class="special">{</span>
4540    <span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">{{</span><span class="identifier">a_</span><span class="special">}};</span>
4541    <span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">{{</span><span class="identifier">x_</span><span class="special">}};</span>
4542    <span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">&gt;</span> <span class="identifier">y</span><span class="special">{{</span><span class="identifier">y_</span><span class="special">}};</span>
4543    <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">);</span>
4544    <span class="keyword">return</span> <span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
4545<span class="special">}</span>
4546</pre>
4547<p>
4548      </p>
4549<p>
4550        and the assembly it produces:
4551      </p>
4552<pre class="programlisting"><span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c00</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">0</span><span class="special">&gt;:</span>  <span class="identifier">pushq</span>  <span class="special">%</span><span class="identifier">rbp</span>
4553<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c01</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">1</span><span class="special">&gt;:</span>  <span class="identifier">movq</span>   <span class="special">%</span><span class="identifier">rsp</span><span class="special">,</span> <span class="special">%</span><span class="identifier">rbp</span>
4554<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c04</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">4</span><span class="special">&gt;:</span>  <span class="identifier">mulsd</span>  <span class="special">%</span><span class="identifier">xmm1</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm0</span>
4555<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c08</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">8</span><span class="special">&gt;:</span>  <span class="identifier">addsd</span>  <span class="special">%</span><span class="identifier">xmm2</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm0</span>
4556<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c0c</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">12</span><span class="special">&gt;:</span> <span class="identifier">movapd</span> <span class="special">%</span><span class="identifier">xmm0</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm1</span>
4557<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c10</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">16</span><span class="special">&gt;:</span> <span class="identifier">mulsd</span>  <span class="special">%</span><span class="identifier">xmm1</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm1</span>
4558<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c14</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">20</span><span class="special">&gt;:</span> <span class="identifier">addsd</span>  <span class="special">%</span><span class="identifier">xmm0</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm1</span>
4559<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c18</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">24</span><span class="special">&gt;:</span> <span class="identifier">movapd</span> <span class="special">%</span><span class="identifier">xmm1</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm0</span>
4560<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c1c</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">28</span><span class="special">&gt;:</span> <span class="identifier">popq</span>   <span class="special">%</span><span class="identifier">rbp</span>
4561<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001c1d</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">29</span><span class="special">&gt;:</span> <span class="identifier">retq</span>
4562</pre>
4563<p>
4564        And for the equivalent function using builtin expressions:
4565      </p>
4566<p>
4567</p>
4568<pre class="programlisting"><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">eval_as_cpp_expr</span><span class="special">(</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">y</span><span class="special">)</span>
4569<span class="special">{</span>
4570    <span class="keyword">return</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">);</span>
4571<span class="special">}</span>
4572</pre>
4573<p>
4574      </p>
4575<p>
4576        the assembly is:
4577      </p>
4578<pre class="programlisting"><span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e10</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">0</span><span class="special">&gt;:</span>  <span class="identifier">pushq</span>  <span class="special">%</span><span class="identifier">rbp</span>
4579<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e11</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">1</span><span class="special">&gt;:</span>  <span class="identifier">movq</span>   <span class="special">%</span><span class="identifier">rsp</span><span class="special">,</span> <span class="special">%</span><span class="identifier">rbp</span>
4580<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e14</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">4</span><span class="special">&gt;:</span>  <span class="identifier">mulsd</span>  <span class="special">%</span><span class="identifier">xmm1</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm0</span>
4581<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e18</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">8</span><span class="special">&gt;:</span>  <span class="identifier">addsd</span>  <span class="special">%</span><span class="identifier">xmm2</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm0</span>
4582<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e1c</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">12</span><span class="special">&gt;:</span> <span class="identifier">movapd</span> <span class="special">%</span><span class="identifier">xmm0</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm1</span>
4583<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e20</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">16</span><span class="special">&gt;:</span> <span class="identifier">mulsd</span>  <span class="special">%</span><span class="identifier">xmm1</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm1</span>
4584<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e24</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">20</span><span class="special">&gt;:</span> <span class="identifier">addsd</span>  <span class="special">%</span><span class="identifier">xmm0</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm1</span>
4585<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e28</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">24</span><span class="special">&gt;:</span> <span class="identifier">movapd</span> <span class="special">%</span><span class="identifier">xmm1</span><span class="special">,</span> <span class="special">%</span><span class="identifier">xmm0</span>
4586<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e2c</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">28</span><span class="special">&gt;:</span> <span class="identifier">popq</span>   <span class="special">%</span><span class="identifier">rbp</span>
4587<span class="identifier">arithmetic_perf</span><span class="special">[</span><span class="number">0</span><span class="identifier">x100001e2d</span><span class="special">]</span> <span class="special">&lt;+</span><span class="number">29</span><span class="special">&gt;:</span> <span class="identifier">retq</span>
4588</pre>
4589<p>
4590        If we increase the number of terminals by a factor of four:
4591      </p>
4592<p>
4593</p>
4594<pre class="programlisting"><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span>
4595<span class="identifier">eval_as_yap_expr_4x</span><span class="special">(</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">a_</span><span class="special">,</span> <span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">x_</span><span class="special">,</span> <span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span> <span class="identifier">y_</span><span class="special">)</span>
4596<span class="special">{</span>
4597    <span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">{{</span><span class="identifier">a_</span><span class="special">}};</span>
4598    <span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">{{</span><span class="identifier">x_</span><span class="special">}};</span>
4599    <span class="identifier">term</span><span class="special">&lt;</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">&gt;</span> <span class="identifier">y</span><span class="special">{{</span><span class="identifier">y_</span><span class="special">}};</span>
4600    <span class="keyword">auto</span> <span class="identifier">expr</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span>
4601                <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span>
4602                <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span>
4603                <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">*</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">);</span>
4604    <span class="keyword">return</span> <span class="identifier">yap</span><span class="special">::</span><span class="identifier">evaluate</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);</span>
4605<span class="special">}</span>
4606</pre>
4607<p>
4608      </p>
4609<p>
4610        the results are the same: in this simple case, the Boost.YAP and builtin
4611        expressions result in the same object code.
4612      </p>
4613<p>
4614        However, increasing the number of terminals by an additional factor of 2.5
4615        (for a total of 90 terminals), the inliner can no longer do as well for Boost.YAP
4616        expressions as for builtin ones.
4617      </p>
4618<p>
4619        More complex nonarithmetic code produces more mixed results. For example,
4620        here is a function using code from the Map Assign example:
4621      </p>
4622<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">make_map_with_boost_yap</span> <span class="special">()</span>
4623<span class="special">{</span>
4624    <span class="keyword">return</span> <span class="identifier">map_list_of</span>
4625        <span class="special">(</span><span class="string">"&lt;"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span>
4626        <span class="special">(</span><span class="string">"&lt;="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span>
4627        <span class="special">(</span><span class="string">"&gt;"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
4628        <span class="special">(</span><span class="string">"&gt;="</span><span class="special">,</span><span class="number">4</span><span class="special">)</span>
4629        <span class="special">(</span><span class="string">"="</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
4630        <span class="special">(</span><span class="string">"&lt;&gt;"</span><span class="special">,</span><span class="number">6</span><span class="special">)</span>
4631        <span class="special">;</span>
4632<span class="special">}</span>
4633</pre>
4634<p>
4635        By contrast, here is the Boost.Assign version of the same function:
4636      </p>
4637<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">make_map_with_boost_assign</span> <span class="special">()</span>
4638<span class="special">{</span>
4639    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">assign</span><span class="special">::</span><span class="identifier">map_list_of</span>
4640        <span class="special">(</span><span class="string">"&lt;"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span>
4641        <span class="special">(</span><span class="string">"&lt;="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span>
4642        <span class="special">(</span><span class="string">"&gt;"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span>
4643        <span class="special">(</span><span class="string">"&gt;="</span><span class="special">,</span><span class="number">4</span><span class="special">)</span>
4644        <span class="special">(</span><span class="string">"="</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
4645        <span class="special">(</span><span class="string">"&lt;&gt;"</span><span class="special">,</span><span class="number">6</span><span class="special">)</span>
4646        <span class="special">;</span>
4647<span class="special">}</span>
4648</pre>
4649<p>
4650        Here is how you might do it "manually":
4651      </p>
4652<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">make_map_manually</span> <span class="special">()</span>
4653<span class="special">{</span>
4654    <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">retval</span><span class="special">;</span>
4655    <span class="identifier">retval</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"&lt;"</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span>
4656    <span class="identifier">retval</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"&lt;="</span><span class="special">,</span><span class="number">2</span><span class="special">);</span>
4657    <span class="identifier">retval</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"&gt;"</span><span class="special">,</span> <span class="number">3</span><span class="special">);</span>
4658    <span class="identifier">retval</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"&gt;="</span><span class="special">,</span><span class="number">4</span><span class="special">);</span>
4659    <span class="identifier">retval</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"="</span><span class="special">,</span> <span class="number">5</span><span class="special">);</span>
4660    <span class="identifier">retval</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"&lt;&gt;"</span><span class="special">,</span><span class="number">6</span><span class="special">);</span>
4661    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
4662<span class="special">}</span>
4663</pre>
4664<p>
4665        Finally, here is the same map created from an initializer list:
4666      </p>
4667<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">make_map_inializer_list</span> <span class="special">()</span>
4668<span class="special">{</span>
4669    <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</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">&gt;</span> <span class="identifier">retval</span> <span class="special">=</span> <span class="special">{</span>
4670        <span class="special">{</span><span class="string">"&lt;"</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
4671        <span class="special">{</span><span class="string">"&lt;="</span><span class="special">,</span><span class="number">2</span><span class="special">},</span>
4672        <span class="special">{</span><span class="string">"&gt;"</span><span class="special">,</span> <span class="number">3</span><span class="special">},</span>
4673        <span class="special">{</span><span class="string">"&gt;="</span><span class="special">,</span><span class="number">4</span><span class="special">},</span>
4674        <span class="special">{</span><span class="string">"="</span><span class="special">,</span> <span class="number">5</span><span class="special">},</span>
4675        <span class="special">{</span><span class="string">"&lt;&gt;"</span><span class="special">,</span><span class="number">6</span><span class="special">}</span>
4676    <span class="special">};</span>
4677    <span class="keyword">return</span> <span class="identifier">retval</span><span class="special">;</span>
4678<span class="special">}</span>
4679</pre>
4680<p>
4681        All of these produce roughly the same amount of assembly instructions. Benchmarking
4682        these four functions with Google Benchmark yields these results:
4683      </p>
4684<div class="table">
4685<a name="boost_yap.manual.object_code.runtimes_of_different_map_constructions"></a><p class="title"><b>Table 47.5. Runtimes of Different Map Constructions</b></p>
4686<div class="table-contents"><table class="table" summary="Runtimes of Different Map Constructions">
4687<colgroup>
4688<col>
4689<col>
4690</colgroup>
4691<thead><tr>
4692<th>
4693                <p>
4694                  Function
4695                </p>
4696              </th>
4697<th>
4698                <p>
4699                  Time (ns)
4700                </p>
4701              </th>
4702</tr></thead>
4703<tbody>
4704<tr>
4705<td>
4706                <p>
4707                  make_map_with_boost_yap()
4708                </p>
4709              </td>
4710<td>
4711                <p>
4712                  1285
4713                </p>
4714              </td>
4715</tr>
4716<tr>
4717<td>
4718                <p>
4719                  make_map_with_boost_assign()
4720                </p>
4721              </td>
4722<td>
4723                <p>
4724                  1459
4725                </p>
4726              </td>
4727</tr>
4728<tr>
4729<td>
4730                <p>
4731                  make_map_manually()
4732                </p>
4733              </td>
4734<td>
4735                <p>
4736                  985
4737                </p>
4738              </td>
4739</tr>
4740<tr>
4741<td>
4742                <p>
4743                  make_map_inializer_list()
4744                </p>
4745              </td>
4746<td>
4747                <p>
4748                  954
4749                </p>
4750              </td>
4751</tr>
4752</tbody>
4753</table></div>
4754</div>
4755<br class="table-break"><p>
4756        The Boost.YAP-based implementation finishes in the middle of the pack.
4757      </p>
4758<p>
4759        In general, the expression trees produced by Boost.YAP get evaluated down
4760        to something close to the hand-written equivalent. There is an abstraction
4761        penalty, but it is small for reasonably-sized expressions.
4762      </p>
4763</div>
4764</div>
4765<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
4766<td align="left"></td>
4767<td align="right"><div class="copyright-footer">Copyright © 2018 T. Zachary Laine<p>
4768        Distributed under the Boost Software License, Version 1.0. (See accompanying
4769        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>)
4770      </p>
4771</div></td>
4772</tr></table>
4773<hr>
4774<div class="spirit-nav">
4775<a accesskey="p" href="../yap.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../yap.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="concepts.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
4776</div>
4777</body>
4778</html>
4779