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"><</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"><</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"><</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"><</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"><</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"><</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)></span> 108 <span class="special">>,</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"><</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"><</span><span class="keyword">double</span><span class="special">></span> 112 <span class="special">></span> 113 <span class="special">></span> 114 <span class="special">>,</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"><</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"><</span><span class="keyword">float</span><span class="special">></span> 118 <span class="special">></span> 119 <span class="special">></span> 120<span class="special">></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"><</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"><</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">></span> 146<span class="special">></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"><></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"><</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"><</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"><</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"><</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)></span> 169 <span class="special">>,</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"><</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"><</span><span class="keyword">double</span><span class="special">></span> 173 <span class="special">></span> 174 <span class="special">></span> 175<span class="special">>,</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"><</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"><</span><span class="keyword">float</span><span class="special">></span> 198<span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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">>;</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"><</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"><</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"><</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"><</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"><</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"><</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)></span> 260 <span class="special">>,</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"><</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"><</span><span class="keyword">double</span><span class="special">></span> 264 <span class="special">></span> 265 <span class="special">></span> 266 <span class="special">>,</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"><</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"><</span><span class="keyword">float</span><span class="special">></span> 270 <span class="special">></span> 271 <span class="special">></span> 272<span class="special">></span> 273<span class="identifier">yap_expr</span> <span class="special">=</span> <span class="identifier">term</span><span class="special"><</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)>{{</span><span class="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<></a></code>. 282 <code class="computeroutput"><a class="link" href="../boost/yap/expression.html" title="Struct template expression">expression<></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<></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<></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<></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<></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"><+></span> 332 <span class="identifier">expr</span><span class="special"><()></span> 333 <span class="identifier">term</span><span class="special"><</span><span class="keyword">double</span> <span class="special">(*)(</span><span class="keyword">double</span><span class="special">)>[=</span><span class="number">1</span><span class="special">]</span> 334 <span class="identifier">term</span><span class="special"><</span><span class="keyword">double</span><span class="special">>[=</span><span class="number">3</span><span class="special">]</span> 335 <span class="identifier">term</span><span class="special"><</span><span class="keyword">float</span><span class="special">>[=</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">&</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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">></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"><</span><span class="identifier">I</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"><</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> 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"><</span><span class="identifier">I</span><span class="special">>)</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"><</span><span class="identifier">I</span><span class="special">>;</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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">T</span> <span class="special">&&)</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"><</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">></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"><</span><span class="identifier">Kind</span><span class="special">>,</span> <span class="identifier">Arg</span> <span class="special">&&...</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"><</span><span class="identifier">Arg</span><span class="special">>(</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"><></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"><></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"><</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">></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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</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"><</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">>(</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"><<</span> <span class="identifier">result</span> <span class="special"><<</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"><...></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"><...></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"><></span></code>, 647 <code class="computeroutput"><span class="identifier">expr</span><span class="special"><></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"><<=()</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<></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"><</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">></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"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">></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"><</span><span class="identifier">I</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"><</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> 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"><</span><span class="identifier">I</span><span class="special">>)</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"><</span><span class="identifier">I</span><span class="special">>;</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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">T</span> <span class="special">&&)</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"><</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">></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"><</span><span class="identifier">Kind</span><span class="special">>,</span> <span class="identifier">Arg</span> <span class="special">&&...</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"><</span><span class="identifier">Arg</span><span class="special">>(</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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> 867 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</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 -> transform(left).</span> 943<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">U</span><span class="special">></span> 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"><</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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">></span> 948 <span class="special">></span> <span class="keyword">const</span> <span class="special">&</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"><</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">></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"><</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">>,</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">&</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">&</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">&</span></code>, 1050 <code class="computeroutput"><span class="keyword">int</span> <span class="keyword">const</span> 1051 <span class="special">&</span></code>, <code class="computeroutput"><span class="keyword">float</span> 1052 <span class="special">&&</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">U</span><span class="special">></span> 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"><</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">comma</span><span class="special">>,</span> <span class="identifier">T</span> <span class="special">&&</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">U</span> <span class="special">&&</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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">T</span> <span class="special">&&>(</span><span class="identifier">t</span><span class="special">)),</span> <span class="special">*</span><span class="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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">U</span> <span class="special">&&>(</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"><</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">></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"><</span><span class="identifier">expr_kind</span><span class="special">::</span><span class="identifier">call</span><span class="special">>,</span> <span class="identifier">Callable</span> <span class="special">&&</span> <span class="identifier">callable</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&&...</span> <span class="identifier">args</span><span class="special">)</span> <span class="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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Callable</span> <span class="special">&&>(</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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Args</span> <span class="special">&&>(</span><span class="identifier">args</span><span class="special">)),</span> <span class="special">*</span><span class="keyword">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"><></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"><></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"><></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"><></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<></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">&</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"><<</span> <span class="identifier">i</span> <span class="special"><<</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">&</span></code> 1726 </p> 1727 </td> 1728<td> 1729 <p> 1730 <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special"><</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"><</span><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)>></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">&</span></code> 1741 </p> 1742 </td> 1743<td> 1744 <p> 1745 <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special"><</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"><</span><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)>></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">&&</span></code> 1756 </p> 1757 </td> 1758<td> 1759 <p> 1760 <code class="computeroutput"><span class="identifier">expr_tmpl</span><span class="special"><</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"><</span><span class="identifier">PARTIAL_DECAY</span><span class="special">(</span><span class="identifier">T</span><span class="special">)>></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">&</span></code> 1775 </p> 1776 </td> 1777<td> 1778 <p> 1779 <code class="computeroutput"><span class="identifier">expr_tmpl</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> 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"><</span><span class="identifier">E</span> <span class="keyword">const</span> 1781 <span class="special">&>></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">&</span></code> 1791 </p> 1792 </td> 1793<td> 1794 <p> 1795 <code class="computeroutput"><span class="identifier">expr_tmpl</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> 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"><</span><span class="identifier">E</span> <span class="special">&>></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">&&</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"><</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">...></span> <span class="keyword">const</span> 1824 <span class="special">&</span></code> 1825 </p> 1826 </td> 1827<td> 1828 <p> 1829 <code class="computeroutput"><span class="identifier">expr_tmpl</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> 1830 <span class="special">...></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"><</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">...></span> <span class="special">&</span></code> 1841 </p> 1842 </td> 1843<td> 1844 <p> 1845 <code class="computeroutput"><span class="identifier">expr_tmpl</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> 1846 <span class="special">...></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"><</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">...></span> <span class="special">&&</span></code> 1857 </p> 1858 </td> 1859<td> 1860 <p> 1861 <code class="computeroutput"><span class="identifier">expr_tmpl</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> 1862 <span class="special">...></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"><</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">></span> 1895</pre> 1896<p> 1897 You must include <code class="computeroutput"><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">print</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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<-> 1936 expr<+> 1937 term<boost::yap::placeholder<4ll>>[=4] 1938 expr<*> 1939 term<double &>[=1] 1940 term<thing>[=<<unprintable-value>>] & 1941 term<char const*>[=lvalue terminal] const & 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"><</span><span class="identifier">op</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">></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">&</span></code> or <code class="computeroutput"><span class="keyword">const</span> 1956 <span class="special">&</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"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&,</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"><<</span><span class="identifier">unprintable</span><span class="special">-</span><span class="identifier">value</span><span class="special">>></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"><</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">></span> 2023 2024<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><<</span> <span class="string">"Hello"</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</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"><</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">></span> 2051 2052<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2053 2054 2055<span class="keyword">template</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> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><<</span> <span class="special">(</span><span class="identifier">T</span> <span class="special">&&</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">T</span> <span class="special">&&>(</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"><</span><span class="identifier">stream_expr</span><span class="special">>(</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"><<</span> <span class="string">"Hello"</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</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"><</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">></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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</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"><</span><span class="identifier">minimal_expr</span><span class="special">>(</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"><</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">>(</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"><<</span> <span class="identifier">result</span> <span class="special"><<</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"><</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">></span> 2156 2157<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><</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">></span> 2193 2194<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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">&&...</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">&&...</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">&&...</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><</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">></span> 2240 2241<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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"><</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">></span> 2289 2290<span class="preprocessor">#include</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">maximum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 2291 2292<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">></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"><</span><span class="identifier">I</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"><</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> 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"><</span><span class="identifier">I</span><span class="special">>)</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"><</span><span class="identifier">I</span><span class="special">>;</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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">T</span> <span class="special">&&)</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"><</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">></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"><</span><span class="identifier">Kind</span><span class="special">>,</span> <span class="identifier">Arg</span> <span class="special">&&...</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"><</span><span class="identifier">Arg</span><span class="special">>(</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">&&...</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">&&...</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">&&...</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"><<</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"><<</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"><<</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"><<</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"><<</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"><<</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 << expr_3_fn(3.0) << std::endl;</span> 2373 2374 <span class="comment">// Static-asserts with "Called with wrong number of args."</span> 2375 <span class="comment">//std::cout << expr_3_fn(3.0, 2.0, 1.0) << 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"><</span><span class="keyword">double</span><span class="special">></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"><</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">></span> 2406 2407<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span> 2408<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 2409<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2410<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 2411 2412 2413<span class="keyword">template</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> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></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<double> 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"><</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></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"><</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"><</span><span class="keyword">double</span><span class="special">>></span> <span class="keyword">const</span> <span class="special">&</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"><</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">></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"><</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">></span> 2446<span class="keyword">auto</span> <span class="identifier">lazy_vector_expr</span><span class="special"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">>::</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"><</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="keyword">double</span><span class="special">></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"><</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"><</span><span class="keyword">double</span><span class="special">>></span> <span class="keyword">const</span> <span class="special">&</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"><</span><span class="identifier">lazy_vector_expr</span><span class="special">,</span> <span class="keyword">double</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> 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"><</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">>></span> 2470 <span class="special">></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"><</span><span class="keyword">double</span><span class="special">></span> <span class="special">&&</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">>>(</span><span class="identifier">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"><</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">></span> 2478 <span class="identifier">lazy_vector</span> <span class="special">&</span> <span class="keyword">operator</span><span class="special">+=</span> <span class="special">(</span><span class="identifier">lazy_vector_expr</span><span class="special"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><</span><span class="keyword">double</span><span class="special">></span> <span class="special">&</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"><</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"><</span><span class="keyword">double</span><span class="special">>(</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"><</span><span class="keyword">double</span><span class="special">>(</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"><</span><span class="keyword">double</span><span class="special">>(</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"><<</span> <span class="identifier">d1</span> <span class="special"><<</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"><<</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> 2499 <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special"><<</span> <span class="char">','</span> <span class="special"><<</span> <span class="identifier">v1</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special"><<</span> <span class="char">'}'</span> <span class="special"><<</span> <span class="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"><</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">></span> 2538 2539<span class="preprocessor">#include</span> <span class="special"><</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">></span> 2540<span class="preprocessor">#include</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">fold</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 2541<span class="preprocessor">#include</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">maximum</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 2542 2543<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span> 2544<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 2545<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2546<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></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"><</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"><</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">&</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"><</span><span class="keyword">double</span><span class="special">></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">&</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"><</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"><</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">&</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">&</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&</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"><</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"><</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">&</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">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="special">&</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"><</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"><</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"><</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">></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"><</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">></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"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><</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">></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"><</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></span> 2642<span class="keyword">struct</span> <span class="identifier">self_evaluating_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">expr_kind</span><span class="special">::</span><span class="identifier">assign</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></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"><</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> 2659 <span class="identifier">self_evaluating_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">expr_kind</span><span class="special">::</span><span class="identifier">multiplies</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">,</span> 2660 <span class="identifier">matrix</span> <span class="special">&</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"><</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> 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">&</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"><</span><span class="keyword">double</span><span class="special">,</span> <span class="identifier">matrix</span> <span class="keyword">const</span> <span class="special">&>(</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"><</span><span class="keyword">decltype</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="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"><</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">></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"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><</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">></span> 2703<span class="identifier">self_evaluating_expr</span><span class="special"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">>::</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"><</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></span> 2709<span class="identifier">self_evaluating_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">expr_kind</span><span class="special">::</span><span class="identifier">assign</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">>::</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"><</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"><</span><span class="identifier">matrix</span><span class="special">></span> 2725 <span class="special">></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"><</span><span class="identifier">matrix</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">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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="number">3</span><span class="special">></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"><</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">></span> 2798<span class="preprocessor">#include</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">print</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 2799 2800<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">array</span><span class="special">></span> 2801<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 2802 2803 2804<span class="keyword">template</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> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></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"><</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></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"><</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><</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">></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 & and</span> 2824 <span class="comment">// int & 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"><</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"><</span><span class="keyword">int</span> <span class="keyword">const</span> <span class="special">&>>{}</span> <span class="special">||</span> 2828 <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</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"><</span><span class="keyword">int</span> <span class="special">&>>{}</span> <span class="special">||</span> 2829 <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</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"><</span><span class="keyword">int</span><span class="special">>>{}</span> <span class="special">||</span> 2830 <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>>>{},</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"><</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></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"><</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><</span><span class="identifier">tarray_expr</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> 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">&</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">ostream</span> <span class="special">&</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"><</span><span class="identifier">tarray_expr</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></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"><<</span> <span class="char">'{'</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="special"><<</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">&</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">ostream</span> <span class="special">&</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"><</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>></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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><<</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special"><<</span> <span class="string">", "</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="special"><<</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"><</span><span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></span> 2875<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">tarray_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">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">></span> <span class="keyword">const</span> <span class="special">&</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"><<</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"><</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">></span> 2879<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&</span> <span class="identifier">os</span><span class="special">,</span> <span class="identifier">tarray_expr</span><span class="special"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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"><<</span> <span class="char">'('</span><span class="special">;</span> 2883 <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">left</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" "</span> <span class="special"><<</span> <span class="identifier">op_string</span><span class="special">(</span><span class="identifier">Kind</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" "</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> 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"><<</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"><</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>></span> 2896 <span class="special">></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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">></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">&</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">&</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 2919 <span class="identifier">tarray</span> <span class="special">&</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">&</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"><</span> <span class="special">::</span><span class="identifier">tarray_expr</span><span class="special">>(</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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> 2928 <span class="identifier">tarray</span> <span class="special">&</span> <span class="identifier">printAssign</span> <span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> 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"><<</span> <span class="special">*</span><span class="keyword">this</span> <span class="special"><<</span> <span class="string">" = "</span> <span class="special"><<</span> <span class="identifier">expr</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> 2937 <span class="identifier">tarray</span> <span class="special">&</span> <span class="identifier">assign</span> <span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> 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"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 2954 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><<</span> <span class="identifier">c</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 2965 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 2966 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">c</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><</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">></span> 2990 2991<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">array</span><span class="special">></span> 2992<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>></span> <span class="keyword">const</span> <span class="special">&</span> <span class="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<> 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"><</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">>></span> 3014<span class="special">>;</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"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">3</span><span class="special">></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">&</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">&</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 3041 <span class="identifier">vec3</span> <span class="special">&</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">&</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"><<</span> <span class="char">'{'</span> <span class="special"><<</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">0</span><span class="special">]</span> 3053 <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">1</span><span class="special">]</span> 3054 <span class="special"><<</span> <span class="string">", "</span> <span class="special"><<</span> <span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="number">2</span><span class="special">]</span> 3055 <span class="special"><<</span> <span class="char">'}'</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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">&</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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></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">&</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"><<</span> <span class="identifier">num</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><<</span> <span class="identifier">num</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><<</span> <span class="identifier">num</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><></span></code>s: 3124 </p> 3125<p> 3126</p> 3127<pre class="programlisting"><span class="preprocessor">#include</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">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 3128 3129<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 3130<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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> 3137 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</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<> 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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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> 3149 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span> <span class="special">&</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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></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">&</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"><</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">></span> 3173<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span> <span class="identifier">assign</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span> <span class="identifier">vec</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</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"><</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"><</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">></span> 3186<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span> <span class="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"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span> <span class="identifier">vec</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</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"><</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">></span> 3202<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">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">>></span> <span class="special">:</span> <span class="identifier">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<> 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">// <</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">// ></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">// <=</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">// >=</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">// &&</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">// &</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"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">;</span> 3230 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">e</span><span class="special">(</span><span class="identifier">n</span><span class="special">);</span> 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"><</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"><</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"><</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"><<</span> <span class="string">" a("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3254 <span class="special"><<</span> <span class="string">" b("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">b</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3255 <span class="special"><<</span> <span class="string">" c("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">c</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3256 <span class="special"><<</span> <span class="string">" d("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">d</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3257 <span class="special"><<</span> <span class="string">" e("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3258 <span class="special"><<</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"><></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<></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<></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"><></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"><></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"><</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">></span> 3296 3297<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">complex</span><span class="special">></span> 3298<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">list</span><span class="special">></span> 3299<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 3300<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></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"><</span><span class="identifier">Iter</span><span class="special">>{</span><span class="identifier">it</span><span class="special">};</span> <span class="special">}</span> 3314 3315 3316<span class="comment">// A container -> 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"><</span><span class="keyword">typename</span> <span class="identifier">Cont</span><span class="special">></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"><</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> 3321 <span class="identifier">Cont</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">cont</span><span class="special">)</span> 3322 <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">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 -> 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"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></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"><</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> 3331 <span class="identifier">iter_wrapper</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">></span> <span class="identifier">wrapper</span><span class="special">)</span> 3332 <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">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"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></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"><</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> 3341 <span class="identifier">iter_wrapper</span><span class="special"><</span><span class="identifier">Iter</span><span class="special">></span> <span class="special">&</span> <span class="identifier">wrapper</span><span class="special">)</span> 3342 <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">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"><</span> 3355 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">></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">></span> 3361<span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="identifier">op_assign</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">Op</span> <span class="special">&&</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">&&</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"><</span> 3380 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">></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">></span> 3385<span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="identifier">assign</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> 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">&</span> <span class="identifier">cont_value</span><span class="special">,</span> <span class="keyword">auto</span> <span class="special">&&</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"><</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">expr_value</span><span class="special">)>(</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"><</span> 3393 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">></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">></span> 3398<span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="keyword">operator</span><span class="special">+=</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> 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">&</span> <span class="identifier">cont_value</span><span class="special">,</span> <span class="keyword">auto</span> <span class="special">&&</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"><</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">expr_value</span><span class="special">)>(</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"><</span> 3406 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span><span class="special">,</span> <span class="keyword">class</span><span class="special">></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">></span> 3411<span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="keyword">operator</span><span class="special">-=</span> <span class="special">(</span><span class="identifier">Cont</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">></span> <span class="special">&</span> <span class="identifier">cont</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr</span><span class="special">)</span> 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">&</span> <span class="identifier">cont_value</span><span class="special">,</span> <span class="keyword">auto</span> <span class="special">&&</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"><</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">expr_value</span><span class="special">)>(</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">></span> 3423<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">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">>></span> <span class="special">:</span> <span class="identifier">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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">A</span><span class="special">></span> 3426<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">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">A</span><span class="special">>></span> <span class="special">:</span> <span class="identifier">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">// <</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">// ></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">// <=</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">// >=</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">// &&</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">// &</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">,</span><span class="identifier">c</span><span class="special">,</span><span class="identifier">d</span><span class="special">;</span> 3461 <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">e</span><span class="special">;</span> 3462 <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">>></span> <span class="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"><</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"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">1.0</span><span class="special">,</span> <span class="number">1.0</span><span class="special">));</span> 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"><</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"><</span><span class="keyword">double</span><span class="special">>(</span><span class="number">0.2</span><span class="special">,</span> <span class="number">1.2</span><span class="special">));</span> 3484 3485 <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">const_iterator</span> <span class="identifier">ei</span> <span class="special">=</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span> 3486 <span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">complex</span><span class="special"><</span><span class="keyword">double</span><span class="special">>>::</span><span class="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"><</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"><<</span> <span class="string">"a("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">a</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3491 <span class="special"><<</span> <span class="string">" b("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">b</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3492 <span class="special"><<</span> <span class="string">" c("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">c</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3493 <span class="special"><<</span> <span class="string">" d("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="identifier">d</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> 3494 <span class="special"><<</span> <span class="string">" e("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">ei</span><span class="special">++</span> 3495 <span class="special"><<</span> <span class="string">" f("</span> <span class="special"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="string">") = "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">fi</span><span class="special">++</span> 3496 <span class="special"><<</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"><</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">></span> 3515 3516<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">map</span><span class="special">></span> 3517<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><</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">></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"><</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">></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"><</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">>,</span> 3528 <span class="identifier">Fn</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Key2</span> <span class="special">&&</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">Value2</span> <span class="special">&&</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"><</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">>(</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"><</span><span class="identifier">Key2</span> <span class="special">&&>(</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"><</span><span class="identifier">Value2</span> <span class="special">&&>(</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"><</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">></span> <span class="special">&</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"><</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">></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"><</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">></span> 3561 <span class="keyword">operator</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">></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"><</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">></span> <span class="identifier">retval</span><span class="special">;</span> 3564 <span class="identifier">map_list_of_transform</span><span class="special"><</span><span class="identifier">Key</span><span class="special">,</span> <span class="identifier">Value</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">></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"><</span><span class="identifier">map_list_of_expr</span><span class="special">>(</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">op</span> <span class="special">=</span> 3582 <span class="identifier">map_list_of</span> 3583 <span class="special">(</span><span class="string">"<"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> 3584 <span class="special">(</span><span class="string">"<="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> 3585 <span class="special">(</span><span class="string">">"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span> 3586 <span class="special">(</span><span class="string">">="</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">"<>"</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"><<</span> <span class="string">"\"<\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"<"</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 3592 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"<=\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"<="</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 3593 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\">\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">">"</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 3594 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\">=\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">">="</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 3595 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"=\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"="</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 3596 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\"<>\" --> "</span> <span class="special"><<</span> <span class="identifier">op</span><span class="special">[</span><span class="string">"<>"</span><span class="special">]</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><</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">></span> 3628 3629<span class="preprocessor">#include</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">concat</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 3630 3631 3632<span class="comment">// A custom expression template for future groups. It supports operators ||</span> 3633<span class="comment">// and &&.</span> 3634<span class="keyword">template</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> <span class="keyword">typename</span> <span class="identifier">Tuple</span><span class="special">></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">&&</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"><</span><span class="identifier">Tuple</span> <span class="special">&&>(</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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"><</span><span class="identifier">T</span><span class="special">>></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">&</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"><</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"><</span><span class="identifier">T</span><span class="special">>></span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">hana</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">T</span><span class="special">>{</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference_t</span><span class="special"><</span><span class="identifier">T</span><span class="special">>>;</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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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"><</span><span class="identifier">T</span><span class="special">></span> 3678 <span class="special">></span> <span class="keyword">const</span> <span class="special">&</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 -> transform(left).</span> 3684 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">U</span><span class="special">></span> 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"><</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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">></span> 3689 <span class="special">></span> <span class="keyword">const</span> <span class="special">&</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 && right -> concat(transform(left), transform(right)).</span> 3698 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">U</span><span class="special">></span> 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"><</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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">></span> 3703 <span class="special">></span> <span class="keyword">const</span> <span class="special">&</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"><</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">></span> 3716<span class="keyword">auto</span> <span class="identifier">future_expr</span><span class="special"><</span><span class="identifier">Kind</span><span class="special">,</span> <span class="identifier">Tuple</span><span class="special">>::</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"><</span><span class="keyword">typename</span> <span class="special">...</span><span class="identifier">T</span><span class="special">></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"><</span><span class="identifier">T</span><span class="special">...>;</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"><</span><span class="identifier">A</span><span class="special">></span> <span class="identifier">a</span><span class="special">;</span> 3733 <span class="identifier">future</span><span class="special"><</span><span class="identifier">B</span><span class="special">></span> <span class="identifier">b</span><span class="special">;</span> 3734 <span class="identifier">future</span><span class="special"><</span><span class="identifier">C</span><span class="special">></span> <span class="identifier">c</span><span class="special">;</span> 3735 <span class="identifier">future</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span><span class="identifier">B</span><span class="special">></span> <span class="special">></span> <span class="identifier">ab</span><span class="special">;</span> 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"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t1</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">a</span> <span class="special">&&</span> <span class="identifier">b</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> 3741 <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t2</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">a</span> <span class="special">||</span> <span class="identifier">a</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> 3742 <span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t3</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">a</span> <span class="special">&&</span> <span class="identifier">b</span> <span class="special">||</span> <span class="identifier">a</span> <span class="special">&&</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> 3743 <span class="identifier">vector</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">>,</span> <span class="identifier">C</span><span class="special">></span> <span class="identifier">t4</span> <span class="special">=</span> <span class="special">((</span><span class="identifier">ab</span> <span class="special">||</span> <span class="identifier">ab</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">c</span><span class="special">).</span><span class="identifier">get</span><span class="special">();</span> 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"><</span><span class="identifier">Node</span><span class="special">*>&</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">-></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">-></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">-></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"><</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">></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<>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"><</span><span class="identifier">OPCODE</span> <span class="identifier">Opcode</span><span class="special">></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"><</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"><</span><span class="identifier">OPCODE</span><span class="special">>></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"><</span><span class="identifier">OPCODE</span><span class="special">>{</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 <math.h>, so we have to add trailing underscores.</span> 3872<span class="identifier">autodiff_fn_expr</span><span class="special"><</span><span class="identifier">OP_SIN</span><span class="special">></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"><</span><span class="identifier">OP_COS</span><span class="special">></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"><</span><span class="identifier">OP_SQRT</span><span class="special">></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"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">></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"><</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> 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"><</span><span class="identifier">I</span><span class="special">>)</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"><</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">&</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"><</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="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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></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"><</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">>,</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">&</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"><</span><span class="identifier">autodiff_expr</span><span class="special">>(</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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></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"><</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">>,</span> 3936 <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&</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"><</span><span class="identifier">autodiff_expr</span><span class="special">>(</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"><</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">></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"><</span><span class="identifier">Kind</span><span class="special">>,</span> <span class="identifier">Expr1</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">expr1</span><span class="special">,</span> <span class="identifier">Expr2</span> <span class="keyword">const</span> <span class="special">&</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"><</span><span class="identifier">autodiff_expr</span><span class="special">>(</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"><</span><span class="identifier">autodiff_expr</span><span class="special">>(</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"><</span><span class="identifier">Node</span> <span class="special">*></span> <span class="special">&</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"><</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">></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">&</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">vector</span><span class="special"><</span><span class="identifier">Node</span> <span class="special">*></span> <span class="special">&</span> <span class="identifier">list</span><span class="special">,</span> <span class="identifier">T</span> <span class="special">...</span> <span class="identifier">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">[&</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"><</span><span class="identifier">VNode</span> <span class="special">*>(</span><span class="identifier">n</span><span class="special">);</span> 3998 <span class="identifier">v</span><span class="special">-></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"><</span><span class="identifier">Node</span><span class="special">*>&</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"><</span><span class="keyword">double</span><span class="special">></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"><</span><span class="keyword">double</span><span class="special">></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"><</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">></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"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></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"><</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">T</span> <span class="special">&&</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"><</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">></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"><</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">>,</span> 4071 <span class="identifier">CallableExpr</span> <span class="identifier">callable</span><span class="special">,</span> <span class="identifier">Arg</span> <span class="special">&&...</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"><</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">>(</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"><</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">></span> 4134 4135<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span> 4136<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Iter</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">></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">&</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"><</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">())></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<>, 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"><</span><span class="keyword">typename</span> <span class="identifier">LExpr</span><span class="special">></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"><</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">>,</span> 4178 <span class="identifier">LExpr</span> <span class="special">&&</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"><</span><span class="identifier">LExpr</span><span class="special">>(</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"><</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">></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"><</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">>,</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">&</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"><</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">></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"><</span><span class="keyword">typename</span> <span class="identifier">Assignee</span><span class="special">></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"><</span><span class="identifier">algorithm_t</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">>({</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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">>({</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"><</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">></span> 4291 4292<span class="preprocessor">#include</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">map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 4293<span class="preprocessor">#include</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">at_key</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 4294<span class="preprocessor">#include</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><span class="identifier">hpp</span><span class="special">></span> 4295<span class="preprocessor">#include</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">hpp</span><span class="special">></span> 4296 4297<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 4298<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></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"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">></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"><</span><span class="identifier">I</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">ExprMap</span><span class="special">></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"><</span><span class="keyword">long</span> <span class="keyword">long</span> <span class="identifier">I</span><span class="special">></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"><</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> 4320 <span class="identifier">let_placeholder</span><span class="special"><</span><span class="identifier">I</span><span class="special">></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"><</span><span class="identifier">I</span><span class="special">>))</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"><</span><span class="identifier">I</span><span class="special">>];</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"><</span><span class="keyword">typename</span> <span class="identifier">ExprMap</span><span class="special">></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"><</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">></span> 4346 <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">Expr</span> <span class="special">&&</span> <span class="identifier">expr</span><span class="special">)</span> 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"><</span><span class="identifier">Expr</span><span class="special">>(</span><span class="identifier">expr</span><span class="special">),</span> <span class="identifier">let_terminal_transform</span><span class="special"><</span><span class="identifier">ExprMap</span><span class="special">>{</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<>s to YAP expressions.</span> 4357<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Map</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Exprs</span><span class="special">></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">&&</span> <span class="identifier">map</span><span class="special">,</span> <span class="identifier">Expr</span> <span class="special">&&</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Exprs</span> <span class="special">&&...</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"><</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">)))>::</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"><</span><span class="identifier">I</span><span class="special">::</span><span class="identifier">value</span><span class="special">>;</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"><</span><span class="identifier">map_t</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> 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"><</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">)))>::</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"><</span><span class="identifier">I</span><span class="special">::</span><span class="identifier">value</span><span class="special">>;</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"><</span><span class="identifier">Exprs</span><span class="special">>(</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 > 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"><</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">></span> 4385<span class="keyword">auto</span> <span class="identifier">let</span><span class="special">(</span><span class="identifier">Expr</span> <span class="special">&&</span> <span class="identifier">expr</span><span class="special">,</span> <span class="identifier">Exprs</span> <span class="special">&&...</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"><</span><span class="identifier">Expr</span><span class="special">>(</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"><</span><span class="identifier">Exprs</span><span class="special">>(</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"><</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"><</span><span class="identifier">let_placeholder</span><span class="special"><</span><span class="number">0</span><span class="special">>>></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"><</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"><</span><span class="identifier">let_placeholder</span><span class="special"><</span><span class="number">1</span><span class="special">>>></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"><<</span> <span class="special">--</span><span class="identifier">_a</span> <span class="special"><<</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"><<</span> <span class="identifier">i</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 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"><<</span> <span class="identifier">_a</span> <span class="special"><<</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"><<</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">// << 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"><<</span> <span class="number">3</span><span class="special">)</span> 4451 <span class="special">[</span> 4452 <span class="identifier">_a</span> <span class="special"><<</span> <span class="string">"1"</span><span class="special">,</span> <span class="identifier">_a</span> <span class="special"><<</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"><<</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"><</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">></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<></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<></a></code> 4476 reference expression template (great for prototyping, but not recommended 4477 for production work), include the <code class="computeroutput"><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">hpp</span><span class="special">></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"><</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">></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"><</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">></span></code> 4486 header; this header is not included in the <code class="computeroutput"><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">yap</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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"><</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">></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"><</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">></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"><</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">></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"><+</span><span class="number">0</span><span class="special">>:</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"><+</span><span class="number">1</span><span class="special">>:</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"><+</span><span class="number">4</span><span class="special">>:</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"><+</span><span class="number">8</span><span class="special">>:</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"><+</span><span class="number">12</span><span class="special">>:</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"><+</span><span class="number">16</span><span class="special">>:</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"><+</span><span class="number">20</span><span class="special">>:</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"><+</span><span class="number">24</span><span class="special">>:</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"><+</span><span class="number">28</span><span class="special">>:</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"><+</span><span class="number">29</span><span class="special">>:</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"><+</span><span class="number">0</span><span class="special">>:</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"><+</span><span class="number">1</span><span class="special">>:</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"><+</span><span class="number">4</span><span class="special">>:</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"><+</span><span class="number">8</span><span class="special">>:</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"><+</span><span class="number">12</span><span class="special">>:</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"><+</span><span class="number">16</span><span class="special">>:</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"><+</span><span class="number">20</span><span class="special">>:</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"><+</span><span class="number">24</span><span class="special">>:</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"><+</span><span class="number">28</span><span class="special">>:</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"><+</span><span class="number">29</span><span class="special">>:</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"><</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">></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"><</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">></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"><</span><span class="identifier">user</span><span class="special">::</span><span class="identifier">number</span><span class="special">></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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">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">"<"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> 4626 <span class="special">(</span><span class="string">"<="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> 4627 <span class="special">(</span><span class="string">">"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span> 4628 <span class="special">(</span><span class="string">">="</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">"<>"</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">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">"<"</span><span class="special">,</span> <span class="number">1</span><span class="special">)</span> 4641 <span class="special">(</span><span class="string">"<="</span><span class="special">,</span><span class="number">2</span><span class="special">)</span> 4642 <span class="special">(</span><span class="string">">"</span><span class="special">,</span> <span class="number">3</span><span class="special">)</span> 4643 <span class="special">(</span><span class="string">">="</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">"<>"</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">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">"<"</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">"<="</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">">"</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">">="</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">"<>"</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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">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"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">retval</span> <span class="special">=</span> <span class="special">{</span> 4670 <span class="special">{</span><span class="string">"<"</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span> 4671 <span class="special">{</span><span class="string">"<="</span><span class="special">,</span><span class="number">2</span><span class="special">},</span> 4672 <span class="special">{</span><span class="string">">"</span><span class="special">,</span> <span class="number">3</span><span class="special">},</span> 4673 <span class="special">{</span><span class="string">">="</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">"<>"</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