UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

623 lines (610 loc) 1.16 MB
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Users' Guide</title> <link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> <link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> <link rel="up" href="../proto.html" title="Chapter&#160;23.&#160;Boost.Proto"> <link rel="prev" href="../proto.html" title="Chapter&#160;23.&#160;Boost.Proto"> <link rel="next" href="reference.html" title="Reference"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table cellpadding="2" width="100%"><tr> <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> <td align="center"><a href="../../../index.html">Home</a></td> <td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> <td align="center"><a href="../../../more/index.htm">More</a></td> </tr></table> <hr> <div class="spirit-nav"> <a accesskey="p" href="../proto.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../proto.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> </div> <div class="section"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="proto.users_guide"></a><a class="link" href="users_guide.html" title="Users' Guide">Users' Guide</a> </h2></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started">Getting Started</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.front_end">Fronts Ends: Defining Terminals and Non-Terminals of Your EDSL</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.intermediate_form">Intermediate Form: Understanding and Introspecting Expressions</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.back_end">Back Ends: Making Expression Templates Do Useful Work</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.examples">Examples</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.resources">Background and Resources</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.glossary">Glossary</a></span></dt> </dl></div> <h4> <a name="proto.users_guide.h0"></a> <span class="phrase"><a name="proto.users_guide.compilers__compiler_construction_toolkits__and_proto"></a></span><a class="link" href="users_guide.html#proto.users_guide.compilers__compiler_construction_toolkits__and_proto">Compilers, Compiler Construction Toolkits, and Proto</a> </h4> <p> Most compilers have front ends and back ends. The front end parses the text of an input program into some intermediate form like an abstract syntax tree, and the back end takes the intermediate form and generates an executable from it. </p> <p> A library built with Proto is essentially a compiler for an embedded domain-specific language (EDSL). It also has a front end, an intermediate form, and a back end. The front end is comprised of the symbols (a.k.a., terminals), members, operators and functions that make up the user-visible aspects of the EDSL. The back end is made of evaluation contexts and transforms that give meaning and behavior to the expression templates generated by the front end. In between is the intermediate form: the expression template itself, which is an abstract syntax tree in a very real sense. </p> <p> To build a library with Proto, you will first decide what your interface will be; that is, you'll design a programming language for your domain and build the front end with tools provided by Proto. Then you'll design the back end by writing evaluation contexts and/or transforms that accept expression templates and do interesting things with them. </p> <p> This users' guide is organized as follows. After a <a class="link" href="users_guide.html#boost_proto.users_guide.getting_started" title="Getting Started">Getting Started guide</a>, we'll cover the tools Proto provides for defining and manipulating the three major parts of a compiler: </p> <div class="variablelist"> <p class="title"><b></b></p> <dl class="variablelist"> <dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.front_end" title="Fronts Ends: Defining Terminals and Non-Terminals of Your EDSL">Front Ends</a></span></dt> <dd><p> How to define the aspects of your EDSL with which your users will interact directly. </p></dd> <dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.intermediate_form" title="Intermediate Form: Understanding and Introspecting Expressions">Intermediate Form</a></span></dt> <dd><p> What Proto expression templates look like, how to discover their structure and access their constituents. </p></dd> <dt><span class="term"><a class="link" href="users_guide.html#boost_proto.users_guide.back_end" title="Back Ends: Making Expression Templates Do Useful Work">Back Ends</a></span></dt> <dd><p> How to define evaluation contexts and transforms that make expression templates do interesting things. </p></dd> </dl> </div> <p> After that, you may be interested in seeing some <a class="link" href="users_guide.html#boost_proto.users_guide.examples" title="Examples">Examples</a> to get a better idea of how the pieces all fit together. </p> <div class="section"> <div class="titlepage"><div><div><h3 class="title"> <a name="boost_proto.users_guide.getting_started"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started" title="Getting Started">Getting Started</a> </h3></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto">Installing Proto</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.naming">Naming Conventions</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.hello_world">Hello World</a></span></dt> <dt><span class="section"><a href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator">Hello Calculator</a></span></dt> </dl></div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="boost_proto.users_guide.getting_started.installing_proto"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto" title="Installing Proto">Installing Proto</a> </h4></div></div></div> <h6> <a name="boost_proto.users_guide.getting_started.installing_proto.h0"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.installing_proto.getting_proto"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.getting_proto">Getting Proto</a> </h6> <p> You can get Proto by downloading Boost (Proto is in version 1.37 and later), or by accessing Boost's SVN repository on SourceForge.net. Just go to <a href="http://svn.boost.org/trac/boost/wiki/BoostSubversion" target="_top">http://svn.boost.org/trac/boost/wiki/BoostSubversion</a> and follow the instructions there for anonymous SVN access. </p> <h6> <a name="boost_proto.users_guide.getting_started.installing_proto.h1"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.installing_proto.building_with_proto"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.building_with_proto">Building with Proto</a> </h6> <p> Proto is a header-only template library, which means you don't need to alter your build scripts or link to any separate lib file to use it. All you need to do is <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">proto</span><span class="special">/</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>. Or, you might decide to just include the core of Proto (<code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">proto</span><span class="special">/</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>) and whichever contexts and transforms you happen to use. </p> <h6> <a name="boost_proto.users_guide.getting_started.installing_proto.h2"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.installing_proto.requirements"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.requirements">Requirements</a> </h6> <p> Proto depends on Boost. You must use either Boost version 1.34.1 or higher, or the version in SVN trunk. </p> <h6> <a name="boost_proto.users_guide.getting_started.installing_proto.h3"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.installing_proto.supported_compilers"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.installing_proto.supported_compilers">Supported Compilers</a> </h6> <p> Currently, Boost.Proto is known to work on the following compilers: </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"> Visual C++ 8 and higher </li> <li class="listitem"> GNU C++ 3.4 and higher </li> <li class="listitem"> Intel on Linux 8.1 and higher </li> <li class="listitem"> Intel on Windows 9.1 and higher </li> </ul></div> <div class="note"><table border="0" summary="Note"> <tr> <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> <th align="left">Note</th> </tr> <tr><td align="left" valign="top"><p> Please send any questions, comments and bug reports to eric &lt;at&gt; boostpro &lt;dot&gt; com. </p></td></tr> </table></div> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="boost_proto.users_guide.getting_started.naming"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming" title="Naming Conventions">Naming Conventions</a> </h4></div></div></div> <p> Proto is a large library and probably quite unlike any library you've used before. Proto uses some consistent naming conventions to make it easier to navigate, and they're described below. </p> <h6> <a name="boost_proto.users_guide.getting_started.naming.h0"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.naming.functions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.functions">Functions</a> </h6> <p> All of Proto's functions are defined in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> namespace. For example, there is a function called <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code> defined in <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> that accepts a terminal expression and returns the terminal's value. </p> <h6> <a name="boost_proto.users_guide.getting_started.naming.h1"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.naming.metafunctions"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.metafunctions">Metafunctions</a> </h6> <p> Proto defines <span class="emphasis"><em>metafunctions</em></span> that correspond to each of Proto's free functions. The metafunctions are used to compute the functions' return types. All of Proto's metafunctions live in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span></code> namespace and have the same name as the functions to which they correspond. For instance, there is a class template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special">&lt;&gt;</span></code> that you can use to compute the return type of the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> function. </p> <h6> <a name="boost_proto.users_guide.getting_started.naming.h2"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.naming.function_objects"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.function_objects">Function Objects</a> </h6> <p> Proto defines <span class="emphasis"><em>function object</em></span> equivalents of all of its free functions. (A function object is an instance of a class type that defines an <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> member function.) All of Proto's function object types are defined in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span></code> namespace and have the same name as their corresponding free functions. For example, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span></code> is a class that defines a function object that does the same thing as the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> free function. </p> <h6> <a name="boost_proto.users_guide.getting_started.naming.h3"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.naming.primitive_transforms"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.naming.primitive_transforms">Primitive Transforms</a> </h6> <p> Proto also defines <span class="emphasis"><em>primitive transforms</em></span> -- class types that can be used to compose larger transforms for manipulating expression trees. Many of Proto's free functions have corresponding primitive transforms. These live in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span></code> namespace and their names have a leading underscore. For instance, the transform corresponding to the <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code> function is called <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code>. </p> <p> The following table summarizes the discussion above: </p> <div class="table"> <a name="boost_proto.users_guide.getting_started.naming.t0"></a><p class="title"><b>Table&#160;23.1.&#160;Proto Naming Conventions</b></p> <div class="table-contents"><table class="table" summary="Proto Naming Conventions"> <colgroup> <col> <col> </colgroup> <thead><tr> <th> <p> Entity </p> </th> <th> <p> Example </p> </th> </tr></thead> <tbody> <tr> <td> <p> Free Function </p> </td> <td> <p> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">value</span><span class="special">()</span></code> </p> </td> </tr> <tr> <td> <p> Metafunction </p> </td> <td> <p> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">::</span><span class="identifier">value</span><span class="special">&lt;&gt;</span></code> </p> </td> </tr> <tr> <td> <p> Function Object </p> </td> <td> <p> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">functional</span><span class="special">::</span><span class="identifier">value</span></code> </p> </td> </tr> <tr> <td> <p> Transform </p> </td> <td> <p> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">_value</span></code> </p> </td> </tr> </tbody> </table></div> </div> <br class="table-break"> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="boost_proto.users_guide.getting_started.hello_world"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_world" title="Hello World">Hello World</a> </h4></div></div></div> <p> Below is a very simple program that uses Proto to build an expression template and then execute it. </p> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">proto</span><span class="special">/</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">ostream</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">;</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&amp;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">cout_</span> <span class="special">=</span> <span class="special">{</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">};</span> <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Expr</span> <span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">expr</span> <span class="special">)</span> <span class="special">{</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">default_context</span> <span class="identifier">ctx</span><span class="special">;</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span><span class="identifier">expr</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> <span class="special">}</span> <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">evaluate</span><span class="special">(</span> <span class="identifier">cout_</span> <span class="special">&lt;&lt;</span> <span class="string">"hello"</span> <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="string">" world"</span> <span class="special">);</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> This program outputs the following: </p> <pre class="programlisting">hello, world </pre> <p> This program builds an object representing the output operation and passes it to an <code class="computeroutput"><span class="identifier">evaluate</span><span class="special">()</span></code> function, which then executes it. </p> <p> The basic idea of expression templates is to overload all the operators so that, rather than evaluating the expression immediately, they build a tree-like representation of the expression so that it can be evaluated later. For each operator in an expression, at least one operand must be Protofied in order for Proto's operator overloads to be found. In the expression ... </p> <pre class="programlisting"><span class="identifier">cout_</span> <span class="special">&lt;&lt;</span> <span class="string">"hello"</span> <span class="special">&lt;&lt;</span> <span class="char">','</span> <span class="special">&lt;&lt;</span> <span class="string">" world"</span> </pre> <p> ... the Protofied sub-expression is <code class="computeroutput"><span class="identifier">cout_</span></code>, which is the Proto-ification of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code>. The presence of <code class="computeroutput"><span class="identifier">cout_</span></code> "infects" the expression, and brings Proto's tree-building operator overloads into consideration. Any literals in the expression are then Protofied by wrapping them in a Proto terminal before they are combined into larger Proto expressions. </p> <p> Once Proto's operator overloads have built the expression tree, the expression can be lazily evaluated later by walking the tree. That is what <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">()</span></code> does. It is a general tree-walking expression evaluator, whose behavior is customizable via a <span class="emphasis"><em>context</em></span> parameter. The use of <code class="computeroutput"><a class="link" href="../boost/proto/context/default_context.html" title="Struct default_context">proto::default_context</a></code> assigns the standard meanings to the operators in the expression. (By using a different context, you could give the operators in your expressions different semantics. By default, Proto makes no assumptions about what operators actually <span class="emphasis"><em>mean</em></span>.) </p> <h6> <a name="boost_proto.users_guide.getting_started.hello_world.h0"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.hello_world.proto_design_philosophy"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_world.proto_design_philosophy">Proto Design Philosophy</a> </h6> <p> Before we continue, let's use the above example to illustrate an important design principle of Proto's. The expression template created in the <span class="emphasis"><em>hello world</em></span> example is totally general and abstract. It is not tied in any way to any particular domain or application, nor does it have any particular meaning or behavior on its own, until it is evaluated in a <span class="emphasis"><em>context</em></span>. Expression templates are really just heterogeneous trees, which might mean something in one domain, and something else entirely in a different one. </p> <p> As we'll see later, there is a way to create Proto expression trees that are <span class="emphasis"><em>not</em></span> purely abstract, and that have meaning and behaviors independent of any context. There is also a way to control which operators are overloaded for your particular domain. But that is not the default behavior. We'll see later why the default is often a good thing. </p> </div> <div class="section"> <div class="titlepage"><div><div><h4 class="title"> <a name="boost_proto.users_guide.getting_started.hello_calculator"></a><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator" title="Hello Calculator">Hello Calculator</a> </h4></div></div></div> <p> "Hello, world" is nice, but it doesn't get you very far. Let's use Proto to build a EDSL (embedded domain-specific language) for a lazily-evaluated calculator. We'll see how to define the terminals in your mini-language, how to compose them into larger expressions, and how to define an evaluation context so that your expressions can do useful work. When we're done, we'll have a mini-language that will allow us to declare a lazily-evaluated arithmetic expression, such as <code class="computeroutput"><span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span></code>, where <code class="computeroutput"><span class="identifier">_1</span></code> and <code class="computeroutput"><span class="identifier">_2</span></code> are placeholders for values to be passed in when the expression is evaluated. </p> <h6> <a name="boost_proto.users_guide.getting_started.hello_calculator.h0"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.hello_calculator.defining_terminals"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.defining_terminals">Defining Terminals</a> </h6> <p> The first order of business is to define the placeholders <code class="computeroutput"><span class="identifier">_1</span></code> and <code class="computeroutput"><span class="identifier">_2</span></code>. For that, we'll use the <code class="computeroutput"><a class="link" href="../boost/proto/terminal.html" title="Struct template terminal">proto::terminal&lt;&gt;</a></code> metafunction. </p> <pre class="programlisting"><span class="comment">// Define a placeholder type</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">placeholder</span> <span class="special">{};</span> <span class="comment">// Define the Protofied placeholder terminals</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_1</span> <span class="special">=</span> <span class="special">{{}};</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="keyword">const</span> <span class="identifier">_2</span> <span class="special">=</span> <span class="special">{{}};</span> </pre> <p> The initialization may look a little odd at first, but there is a good reason for doing things this way. The objects <code class="computeroutput"><span class="identifier">_1</span></code> and <code class="computeroutput"><span class="identifier">_2</span></code> above do not require run-time construction -- they are <span class="emphasis"><em>statically initialized</em></span>, which means they are essentially initialized at compile time. See the <a class="link" href="appendices.html#boost_proto.appendices.rationale.static_initialization" title="Static Initialization">Static Initialization</a> section in the <a class="link" href="appendices.html#boost_proto.appendices.rationale" title="Appendix C: Rationale">Rationale</a> appendix for more information. </p> <h6> <a name="boost_proto.users_guide.getting_started.hello_calculator.h1"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.hello_calculator.constructing_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.constructing_expression_trees">Constructing Expression Trees</a> </h6> <p> Now that we have terminals, we can use Proto's operator overloads to combine these terminals into larger expressions. So, for instance, we can immediately say things like: </p> <pre class="programlisting"><span class="comment">// This builds an expression template</span> <span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">;</span> </pre> <p> This creates an expression tree with a node for each operator. The type of the resulting object is large and complex, but we are not terribly interested in it right now. </p> <p> So far, the object is just a tree representing the expression. It has no behavior. In particular, it is not yet a calculator. Below we'll see how to make it a calculator by defining an evaluation context. </p> <h6> <a name="boost_proto.users_guide.getting_started.hello_calculator.h2"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.hello_calculator.evaluating_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.evaluating_expression_trees">Evaluating Expression Trees</a> </h6> <p> No doubt you want your expression templates to actually <span class="emphasis"><em>do</em></span> something. One approach is to define an <span class="emphasis"><em>evaluation context</em></span>. The context is like a function object that associates behaviors with the node types in your expression tree. The following example should make it clear. It is explained below. </p> <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">calculator_context</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">callable_context</span><span class="special">&lt;</span> <span class="identifier">calculator_context</span> <span class="keyword">const</span> <span class="special">&gt;</span> <span class="special">{</span> <span class="comment">// Values to replace the placeholders</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">args</span><span class="special">;</span> <span class="comment">// Define the result type of the calculator.</span> <span class="comment">// (This makes the calculator_context "callable".)</span> <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> <span class="comment">// Handle the placeholders:</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">&gt;</span> <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">tag</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">,</span> <span class="identifier">placeholder</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">&gt;)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">args</span><span class="special">[</span><span class="identifier">I</span><span class="special">];</span> <span class="special">}</span> <span class="special">};</span> </pre> <p> In <code class="computeroutput"><span class="identifier">calculator_context</span></code>, we specify how Proto should evaluate the placeholder terminals by defining the appropriate overloads of the function call operator. For any other nodes in the expression tree (e.g., arithmetic operations or non-placeholder terminals), Proto will evaluate the expression in the "default" way. For example, a binary plus node is evaluated by first evaluating the left and right operands and adding the results. Proto's default evaluator uses the <a href="../../../libs/typeof/index.html" target="_top">Boost.Typeof</a> library to compute return types. </p> <p> Now that we have an evaluation context for our calculator, we can use it to evaluate our arithmetic expressions, as below: </p> <pre class="programlisting"><span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">45</span><span class="special">);</span> <span class="comment">// the value of _1 is 45</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">50</span><span class="special">);</span> <span class="comment">// the value of _2 is 50</span> <span class="comment">// Create an arithmetic expression and immediately evaluate it</span> <span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(</span> <span class="special">(</span><span class="identifier">_2</span> <span class="special">-</span> <span class="identifier">_1</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">_2</span> <span class="special">*</span> <span class="number">100</span><span class="special">,</span> <span class="identifier">ctx</span> <span class="special">);</span> <span class="comment">// This prints "10"</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">d</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> </pre> <p> Later, we'll see how to define more interesting evaluation contexts and expression transforms that give you total control over how your expressions are evaluated. </p> <h6> <a name="boost_proto.users_guide.getting_started.hello_calculator.h3"></a> <span class="phrase"><a name="boost_proto.users_guide.getting_started.hello_calculator.customizing_expression_trees"></a></span><a class="link" href="users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.customizing_expression_trees">Customizing Expression Trees</a> </h6> <p> Our calculator EDSL is already pretty useful, and for many EDSL scenarios, no more would be needed. But let's keep going. Imagine how much nicer it would be if all calculator expressions overloaded <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> so that they could be used as function objects. We can do that by creating a calculator <span class="emphasis"><em>domain</em></span> and telling Proto that all expressions in the calculator domain have extra members. Here is how to define a calculator domain: </p> <pre class="programlisting"><span class="comment">// Forward-declare an expression wrapper</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">calculator</span><span class="special">;</span> <span class="comment">// Define a calculator domain. Expression within</span> <span class="comment">// the calculator domain will be wrapped in the</span> <span class="comment">// calculator&lt;&gt; expression wrapper.</span> <span class="keyword">struct</span> <span class="identifier">calculator_domain</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">domain</span><span class="special">&lt;</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">generator</span><span class="special">&lt;</span><span class="identifier">calculator</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">{};</span> </pre> <p> The <code class="computeroutput"><span class="identifier">calculator</span><span class="special">&lt;&gt;</span></code> type will be an expression wrapper. It will behave just like the expression that it wraps, but it will have extra member functions that we will define. The <code class="computeroutput"><span class="identifier">calculator_domain</span></code> is what informs Proto about our wrapper. It is used below in the definition of <code class="computeroutput"><span class="identifier">calculator</span><span class="special">&lt;&gt;</span></code>. Read on for a description. </p> <pre class="programlisting"><span class="comment">// Define a calculator expression wrapper. It behaves just like</span> <span class="comment">// the expression it wraps, but with an extra operator() member</span> <span class="comment">// function that evaluates the expression. </span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Expr</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">calculator</span> <span class="special">:</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;,</span> <span class="identifier">calculator_domain</span><span class="special">&gt;</span> <span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">,</span> <span class="identifier">calculator</span><span class="special">&lt;</span><span class="identifier">Expr</span><span class="special">&gt;,</span> <span class="identifier">calculator_domain</span><span class="special">&gt;</span> <span class="identifier">base_type</span><span class="special">;</span> <span class="identifier">calculator</span><span class="special">(</span><span class="identifier">Expr</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">expr</span> <span class="special">=</span> <span class="identifier">Expr</span><span class="special">())</span> <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span><span class="identifier">expr</span><span class="special">)</span> <span class="special">{}</span> <span class="keyword">typedef</span> <span class="keyword">double</span> <span class="identifier">result_type</span><span class="special">;</span> <span class="comment">// Overload operator() to invoke proto::eval() with</span> <span class="comment">// our calculator_context.</span> <span class="keyword">double</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">double</span> <span class="identifier">a1</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">a2</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="identifier">calculator_context</span> <span class="identifier">ctx</span><span class="special">;</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a1</span><span class="special">);</span> <span class="identifier">ctx</span><span class="special">.</span><span class="identifier">args</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a2</span><span class="special">);</span> <span class="keyword">return</span> <span class="identifier">proto</span><span class="special">::</span><span class="identifier">eval</span><span class="special">(*</span><span class="keyword">this</span><span class="special">,</span> <span class="identifier">ctx</span><span class="special">);</span> <span class="special">}</span> <span class="special">};</span> </pre> <p> The <code class="computeroutput"><span class="identifier">calculator</span><span class="special">&lt;&gt;</span></code> struct is an expression <span class="emphasis"><em>extension</em></span>. It uses <code class="computeroutput"><span class="identifier">proto</span><span class="special">::</span><span class="identifier">extends</span><span class="special">&lt;&gt;</span></code> to effectively add additional members to an expression type. When composing larger expressions from smaller ones, Proto notes what domain the smaller expressions are in. The larger expression is in the same domain and is automatically wrapped in the domain's extension wrapper. </p> <p> All that remains to be done is to put our placeholders in the calculator domain. We do that by wrapping them in our <code class="computeroutput"><span class="identifier">calculator</span><span class="special">&lt;&gt;</span></code> wrapper, as below: </p> <pre class="programlisting"><span class="comment">// Define the Protofied placeholder terminals, in the</span> <span class="comment">// calculator domain.</span> <span class="identifier">calculator</span><span class="special">&lt;</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">_1</span><span class="special">;</span> <span class="identifier">calculator</span><span class="special">&lt;</span><span class="identifier">proto</span><span class="special">::</span><span class="identifier">terminal</span><span class="special">&lt;</span><span class="identifier">placeholder</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">_2</span><span class="special">;</span> </pre> <p> Any larger expression that contain these placeholders will automatically be wrapped in the <code class="computeroutput"><span class="identifier">calculator</span><span class="special">&lt;&gt;</span></code> wrapper and have our <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> overload. That means we can use them as function objects as follows. </p> <pre class="programlisting"><span class="keyword">double</span> <span class="identifier">result</span> <span class