spirit/classic/phoenix/doc/operators.html
Joel de Guzman 994d4e48cc moving stuff to classic spirit
[SVN r44163]
2008-04-10 23:51:31 +00:00

102 lines
8.1 KiB
HTML

<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Operators</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="functions.html">
<link rel="next" href="statements.html">
</head>
<body>
<table width="100%" height="48" border="0" background="theme/bkd2.gif" cellspacing="2">
<tr>
<td width="10">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Operators</b></font>
</td>
<td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" align="right" border="0"></a></td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="statements.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<a name="lazy_operators"></a><h2>Lazy operators</h2><p>
This facility provides a mechanism for lazily evaluating operators. Syntactically, a lazy operator looks and feels like an ordinary C/C++ infix, prefix or postfix operator. The operator application looks the same. However, unlike ordinary operators, the actual operator execution is deferred. Samples:</p>
<code><pre>
<span class=identifier>arg1 </span><span class=special>+ </span><span class=identifier>arg2
</span><span class=number>1 </span><span class=special>+ </span><span class=identifier>arg1 </span><span class=special>* </span><span class=identifier>arg2
</span><span class=number>1 </span><span class=special>/ -</span><span class=identifier>arg1
</span><span class=identifier>arg1 </span><span class=special>&lt; </span><span class=number>150
</span></pre></code>
<p>
We have seen the lazy operators in action (see sample2.cpp) above. Let's go back and examine it a little bit further:</p>
<code><pre>
<span class=identifier>find_if</span><span class=special>(</span><span class=identifier>c</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(), </span><span class=identifier>c</span><span class=special>.</span><span class=identifier>end</span><span class=special>(), </span><span class=identifier>arg1 </span><span class=special>% </span><span class=number>2 </span><span class=special>== </span><span class=number>1</span><span class=special>)
</span></pre></code>
<p>
Through operator overloading, the expression &quot;arg1 % 2 == 1&quot; actually generates a composite. This composite object is passed on to STL's find_if function. In the viewpoint of STL, the composite is simply a functor expecting a single argument, the container's element. For each element in the container 'c', the element is passed on as an argument (arg1) to the composite (functor). The composite (functor) checks if this is an odd value based on the expression &quot;arg1 % 2 == 1&quot; where arg1 is iteratively replaced by the container's element.</p>
<p>
A set of classes implement all the C++ free operators. Like lazy functions (see functions), lazy operators are not immediately executed when invoked. Instead, a composite (see composite) object is created and returned to the caller. Example:</p>
<code><pre>
<span class=special>(</span><span class=identifier>arg1 </span><span class=special>+ </span><span class=identifier>arg2</span><span class=special>) * </span><span class=identifier>arg3
</span></pre></code>
<p>
does nothing more than return a composite. A second function call will evaluate the actual operators. Example:</p>
<code><pre>
<span class=keyword>int </span><span class=identifier>i </span><span class=special>= </span><span class=number>4</span><span class=special>, </span><span class=identifier>j </span><span class=special>= </span><span class=number>5</span><span class=special>, </span><span class=identifier>k </span><span class=special>= </span><span class=number>6</span><span class=special>;
</span><span class=identifier>cout </span><span class=special>&lt;&lt; ((</span><span class=identifier>arg1 </span><span class=special>+ </span><span class=identifier>arg2</span><span class=special>) * </span><span class=identifier>arg3</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=identifier>k</span><span class=special>);
</span></pre></code>
<p>
will print out &quot;54&quot;.</p>
<p>
Arbitrarily complex expressions can be lazily evaluated following three simple rules:</p>
<ol><li>Lazy evaluated binary operators apply when *at least* one of the operands is an actor object (see actor, primitives and composite). Consequently, if one of the operands is not an actor object, it is implicitly converted, by default, to an object of type actor&lt;value&lt;T&gt; &gt; (where T is the original type of the operand).</li><li>Lazy evaluated unary operators apply only to operands which are actor objects.</li><li>The result of a lazy operator is a composite actor object that can in turn apply to rule 1.</li></ol><p>
Example:</p>
<code><pre>
<span class=special>-(</span><span class=identifier>arg1 </span><span class=special>+ </span><span class=number>3 </span><span class=special>+ </span><span class=number>6</span><span class=special>)
</span></pre></code>
<ol><li>Following rule 1, lazy evaluation is triggered since arg1 is an instance of an actor&lt;argument&lt;N&gt; &gt; class (see primitives).</li><li>The immediate right operand &lt;3&gt; is implicitly converted to an actor&lt;value&lt;int&gt; &gt;. Still following rule 1.</li><li>The result of this &quot;arg1 + 3&quot; expression is a composite object, following rule 3.</li><li>Now since &quot;arg1 + 3&quot; is a composite, following rule 1 again, its right operand &lt;6&gt; is implicitly converted to an actor&lt;value&lt;int&gt; &gt;.</li><li>Continuing, the result of &quot;arg1 + 3&quot; ... &quot;+ 6&quot; is again another composite. Rule 3.</li><li>The expression &quot;arg1 + 3 + 6&quot; being a composite, is the operand of the unary operator -. Following rule 2, the result is an actor object.</li><li>Folowing rule 3, the whole thing &quot;-(arg1 + 3 + 6)&quot; is a composite.</li></ol><p>
Lazy-operator application is highly contagious. In most cases, a single argN actor infects all its immediate neighbors within a group (first level or parenthesized expression).</p>
<p>
Take note that although at least one of the operands must be a valid actor class in order for lazy evaluation to take effect, if this is not the case and we still want to lazily evaluate an expression, we can use var(x), val(x) or const(x) to transform the operand into a valid action object (see primitives). Example:</p>
<code><pre>
<span class=identifier>val</span><span class=special>(</span><span class=number>1</span><span class=special>) &lt;&lt; </span><span class=number>3</span><span class=special>;
</span></pre></code>
<p>
Supported operators:</p>
<p>
Unary operators:</p>
<code><pre>
<span class=identifier>prefix</span><span class=special>: ~, !, -, +, ++, --, &amp; (</span><span class=identifier>reference</span><span class=special>), * (</span><span class=identifier>dereference</span><span class=special>)
</span><span class=identifier>postfix</span><span class=special>: ++, --
</span></pre></code>
<p>
Binary operators:</p>
<code><pre>
<span class=special>=, [], +=, -=, *=, /=, %=, &amp;=, |=, ^=, &lt;&lt;=, &gt;&gt;=
+, -, *, /, %, &amp;, |, ^, &lt;&lt;, &gt;&gt;
==, !=, &lt;, &gt;, &lt;=, &gt;=
&amp;&amp;, ||
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="statements.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1">
<p class="copyright">Copyright &copy; 2001-2002 Joel de Guzman<br>
<br>
<font size="2">Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt) </font> </p>
</body>
</html>