|
Boost-Commit : |
From: eric_at_[hidden]
Date: 2008-02-06 19:05:02
Author: eric_niebler
Date: 2008-02-06 19:05:01 EST (Wed, 06 Feb 2008)
New Revision: 43136
URL: http://svn.boost.org/trac/boost/changeset/43136
Log:
reasonably complete user docs for expression evaluation
Text files modified:
trunk/libs/xpressive/proto/doc/evaluation.qbk | 258 +++++++++++++++++++++++++++++++++++++++
trunk/libs/xpressive/proto/doc/protodoc.xml | 6
trunk/libs/xpressive/proto/doc/transforms.qbk | 17 ++
3 files changed, 277 insertions(+), 4 deletions(-)
Modified: trunk/libs/xpressive/proto/doc/evaluation.qbk
==============================================================================
--- trunk/libs/xpressive/proto/doc/evaluation.qbk (original)
+++ trunk/libs/xpressive/proto/doc/evaluation.qbk 2008-02-06 19:05:01 EST (Wed, 06 Feb 2008)
@@ -275,6 +275,84 @@
_default_context_ uses Boost.Typeof to deduce the types of the expressions it
evaluates.
+For example, consider the following "Hello World" example:
+
+ #include <iostream>
+ #include <boost/xpressive/proto/proto.hpp>
+ #include <boost/xpressive/proto/context.hpp>
+ #include <boost/typeof/std/ostream.hpp>
+ using namespace boost;
+
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ // Evaluate the expression with default_context,
+ // to give the operators their C++ meanings:
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+ }
+
+ int main()
+ {
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+ }
+
+This program outputs the following:
+
+[pre
+hello, world
+]
+
+_default_context_ is trivially defined in terms of a `default_eval<>`
+template, as follows:
+
+ // Definition of default_context
+ struct default_context
+ {
+ template<typename Expr>
+ struct eval
+ : default_eval<Expr, default_context const, typename Expr::proto_tag>
+ {};
+ };
+
+There are a bunch of `default_eval<>` specializations, each of which handles
+a different C++ operator. Here, for instance, is the specialization for binary
+addition:
+
+ // A default expression evaluator for binary addition
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::plus>
+ {
+ private:
+ static Expr & s_expr;
+ static Context & s_ctx;
+
+ public:
+ typedef
+ decltype(
+ proto::eval(proto::arg_c<0>(s_expr), s_ctx)
+ + proto::eval(proto::arg_c<1>(s_expr), s_ctx)
+ )
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx)
+ + proto::eval(proto::arg_c<1>(expr), ctx);
+ }
+ };
+
+The above code uses `decltype` to calculate the return type of the function
+call operator. `decltype` is a new keyword in the next version of C++ that gets
+the type of any expression. Most compilers do not yet support `decltype`
+directly, so `default_eval<>` uses the Boost.Typeof library to emulate it. On
+some compilers, that may mean that `default_context` either doesn't work or
+that it requires you to register your types with the Boost.Typeof library.
+Check the documentation for Boost.Typeof to see.
+
[endsect]
[/===================================]
@@ -282,7 +360,66 @@
[/===================================]
The _null_context_ is a simple context that recursively evaluates children
-but does not combine the results in any way and returns void.
+but does not combine the results in any way and returns void. It is useful
+in conjunction with `callable_context<>`, or when defining your own contexts
+which mutate an expression tree in-place rather than accumulate a result, as
+we'll see below.
+
+_null_context_ is trivially implemented in terms of `null_eval<>` as follows:
+
+ // Definition of null_context
+ struct null_context
+ {
+ template<typename Expr>
+ struct eval
+ : null_eval<Expr, null_context const, Expr::proto_arity::value>
+ {};
+ };
+
+And `null_eval<>` is also trivially implemented. Here, for instance is
+a binary `null_eval<>`:
+
+ // Binary null_eval<>
+ template<typename Expr, typename Context>
+ struct null_eval<Expr, Context, 2>
+ {
+ typedef void result_type;
+
+ void operator()(Expr &expr, Context &ctx) const
+ {
+ proto::eval(proto::arg_c<0>(expr), ctx);
+ proto::eval(proto::arg_c<1>(expr), ctx);
+ }
+ };
+
+When would such classes be useful? Imagine you have an expression tree with
+integer terminals, and you would like to increment each integer in-place. You
+might define an evaluation context as follows:
+
+ struct increment_ints
+ {
+ // By default, just evaluate all children by defering
+ // to the null_eval<>
+ template<typename Expr, typename Arg = proto::result_of::arg<Expr>::type>
+ struct eval
+ : null_eval<Expr, increment_ints const>
+ {};
+
+ // Increment integer terminals
+ template<typename Expr>
+ struct eval<Expr, int>
+ {
+ typedef void result_type;
+
+ void operator()(Expr &expr, increment_ints const &) const
+ {
+ ++proto::arg(expr);
+ }
+ };
+ };
+
+In the next section on _callable_context_, we'll see an even simpler way to
+achieve the same thing.
[endsect]
@@ -296,6 +433,125 @@
expressions not handled by an overload are automatically dispatched to a
default evaluation context that you can specify.
+Rather than an evaluation context in its own right, _callable_context_ is more
+properly thought of as a context adaptor. To use it, you must define your own
+context that inherits from _callable_context_.
+
+In the [link boost_proto.users_guide.expression_evaluation.canned_contexts.null_context [^null_context]]
+section, we saw how to implement an evaluation context that increments all the
+integers within an expression tree. Here is how to do the same thing with the
+_callable_context_:
+
+ // An evaluation context that increments all
+ // integer terminals in-place.
+ struct increment_ints
+ : callable_context<
+ increment_ints const // derived context
+ , null_context const // fall-back context
+ >
+ {
+ typedef void result_type;
+
+ // Handle int terminals here:
+ void operator()(proto::tag::terminal, int &i) const
+ {
+ ++i;
+ }
+ };
+
+With such a context, we can do the following:
+
+ literal<int> i = 0, j = 10;
+ proto::eval( i - j * 3.14, increment_ints() );
+
+ std::cout << "i = " << i.get() << std::endl;
+ std::cout << "j = " << j.get() << std::endl;
+
+This program outputs the following, which shows that the integers `i` and `j`
+have been incremented by `1`:
+
+[pre
+i = 1
+j = 11
+]
+
+In the `increment_ints` context, we didn't have to define any nested `eval<>`
+templates. That's because _callable_context_ implements them for us.
+_callable_context_ takes two template parameters: the derived context and a
+fall-back context. For each node in the expression tree being evaluated,
+_callable_context_ checks to see if there is an overloaded `operator()` in the
+derived context that accepts it. Given some expression `expr` of type `Expr`,
+and a context `ctx`, it attempts to call:
+
+ ctx(
+ typename Expr::proto_tag()
+ , proto::arg_c<0>(expr)
+ , proto::arg_c<1>(expr)
+ ...
+ );
+
+Using function overloading and metaprogramming tricks, _callable_context_ can
+detect at compile-time whether such a function exists or not. If so, that
+function is called. If not, the current expression is passed to the fall-back
+evaluation context to be processed.
+
+We saw another example of the _callable_context_ when we looked at the simple
+calculator expression evaluator. There, we wanted to customize the evaluation
+of placeholder terminals, and delegate the handling of all other nodes to the
+_default_context_. We did that as follows:
+
+ // An evaluation context for calculator expressions that
+ // explicitly handles placeholder terminals, but defers the
+ // processing of all other nodes to the default_context.
+ struct calculator_context
+ : proto::callable_context< calculator_context const >
+ {
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ // Define the result type of the calculator.
+ typedef double result_type;
+
+ // Handle the placeholders:
+ double operator()(proto::tag::terminal, placeholder1) const
+ {
+ return this->d1_;
+ }
+
+ double operator()(proto::tag::terminal, placeholder2) const
+ {
+ return this->d2_;
+ }
+
+ private:
+ double d1_, d2_;
+ };
+
+In this case, we didn't specify a fall-back context. In that case,
+_callable_context_ uses the _default_context_. With the above
+`calculator_context` and a couple of appropriately defined placeholder
+terminals, we can evaluate calculator expressions, as demonstrated
+below:
+
+ struct placeholder1 {};
+ struct placeholder2 {};
+ terminal<placeholder1>::type const _1 = {{}};
+ terminal<placeholder2>::type const _2 = {{}};
+ // ...
+
+ double j = proto::eval(
+ (_2 - _1) / _2 * 100
+ , calculator_context(4, 5)
+ );
+ std::cout << "j = " << j << std::endl;
+
+The above code displays the following:
+
+[pre
+j = 20
+]
+
[endsect]
[endsect]
Modified: trunk/libs/xpressive/proto/doc/protodoc.xml
==============================================================================
--- trunk/libs/xpressive/proto/doc/protodoc.xml (original)
+++ trunk/libs/xpressive/proto/doc/protodoc.xml 2008-02-06 19:05:01 EST (Wed, 06 Feb 2008)
@@ -243,7 +243,7 @@
</template><parameter name="expr"><paramtype>proto::expr< Tag, Args, 0 > const &</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
<template-type-parameter name="T"/>
</template><parameter name="t"><paramtype>T const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><constructor><parameter name="depth"><paramtype>int</paramtype><default>0</default><description><para>The starting indentation depth for this node. Children nodes will be displayed at a starting depth of <computeroutput>depth+4</computeroutput>. </para></description></parameter><parameter name="sout"><paramtype>std::ostream &</paramtype><default>std::cout</default><description><para>The <computeroutput>ostream</computeroutput> to which the expression tree will be written. </para></description></parameter><description><para>
-</para></description></constructor></struct></namespace><namespace name="tag"><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::posit</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::negate</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::dereference</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::complement</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::address_of</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_not</classname></paramtype></parameter></
function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><param
eter name=""><paramtype><classname>tag::multiplies</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater</classname></paramtype></parameter></f
unction><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::not_equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *<
/type><parameter name=""><paramtype><classname>tag::bitwise_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::comma</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::mem_ptr</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left_assign</cl
assname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus_assign</classname></paramtype></parameter></fun
ction><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::subscript</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::if_else_</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::function</classname></paramtype></parameter></function></namespace><overloaded-function name="
display_expr"><signature><type>void</type><template>
+</para></description></constructor><method-group name="private member functions"/><copy-assignment><parameter name=""><paramtype><classname>display_expr</classname> const &</paramtype></parameter></copy-assignment></struct></namespace><namespace name="tag"><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::posit</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::negate</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::dereference</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::complement</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::address_of</classname></pa
ramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_not</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left</classname></paramtype></parameter></function><function name="proto_tag_name"><type>cha
r const *</type><parameter name=""><paramtype><classname>tag::shift_right</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less</classname><
/paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::not_equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_or</classname></paramtype></parameter></function><function name="proto_tag_nam
e"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::comma</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::mem_ptr</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname
>tag::assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus_assign</classname></paramt
ype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::subscript</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::if_else_</classname></paramtype></parameter></function><function name
="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::function</classname></paramtype></parameter></function></namespace><overloaded-function name="display_expr"><signature><type>void</type><template>
<template-type-parameter name="Expr"/>
</template><parameter name="expr"><paramtype>Expr const &</paramtype><description><para>The Proto expression tree to pretty-print </para></description></parameter><parameter name="sout"><paramtype>std::ostream &</paramtype><description><para>The <computeroutput>ostream</computeroutput> to which the output should be written. </para></description></parameter></signature><signature><type>void</type><template>
<template-type-parameter name="Expr"/>
@@ -298,7 +298,7 @@
<template-type-parameter name="This"/>
<template-type-parameter name="Expr"/>
<template-type-parameter name="Context"/>
- </template><specialization><template-arg>This(Expr</template-arg><template-arg>Context)</template-arg></specialization><typedef name="type"><type><classname>proto::result_of::eval</classname>< typename remove_reference< Expr >::type, typename remove_reference< Context >::type >::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>< Expr, Context >::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>Context)</template-arg></specialization><typedef name="type"><type><classname>proto::result_of::eval</classname>< typename remove_reference< Expr >::type, typename remove_reference< Context >::type >::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>< Expr, Context >::type</type><template>
<template-type-parameter name="Expr"/>
<template-type-parameter name="Context"/>
</template><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter><purpose>Evaluate a given Proto expression with a given context. </purpose><description><para>
@@ -775,7 +775,7 @@
</para></description><returns><para>Generator::make(deep_copy(expr)) </para></returns></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/literal.hpp"><para>The literal<> terminal wrapper, and the proto::lit() function for creating literal<> wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="utility"><struct name="literal"><template>
<template-type-parameter name="T"/>
<template-type-parameter name="Domain"/>
- </template><purpose>A simple wrapper for a terminal, provided for ease of use. </purpose><description><para>A simple wrapper for a terminal, provided for ease of use. In all cases, <computeroutput>literal<X> l(x);</computeroutput> is equivalent to <computeroutput>terminal<X>type l = {x};</computeroutput>.</para><para>The <computeroutput>Domain</computeroutput> template parameter defaults to <computeroutput>proto::default_domain</computeroutput>. </para></description><method-group name="public member functions"/><constructor><template>
+ </template><purpose>A simple wrapper for a terminal, provided for ease of use. </purpose><description><para>A simple wrapper for a terminal, provided for ease of use. In all cases, <computeroutput>literal<X> l(x);</computeroutput> is equivalent to <computeroutput>terminal<X>type l = {x};</computeroutput>.</para><para>The <computeroutput>Domain</computeroutput> template parameter defaults to <computeroutput>proto::default_domain</computeroutput>. </para></description><typedef name="value_type"><type><classname>proto::result_of::arg</classname>< terminal_type >::type</type></typedef><typedef name="reference"><type><classname>proto::result_of::arg</classname>< terminal_type >::reference</type></typedef><typedef name="const_reference"><type><classname>proto::result_of::arg</classname>< terminal_type >::const_reference</type></typedef><method-group name="public member functions"><method name="get" cv=""><type>reference</type></method><method name="get" cv="const"><type>const_ref
erence</type></method></method-group><constructor><template>
<template-type-parameter name="U"/>
</template><parameter name="u"><paramtype>U &</paramtype></parameter></constructor><constructor><template>
<template-type-parameter name="U"/>
Modified: trunk/libs/xpressive/proto/doc/transforms.qbk
==============================================================================
--- trunk/libs/xpressive/proto/doc/transforms.qbk (original)
+++ trunk/libs/xpressive/proto/doc/transforms.qbk 2008-02-06 19:05:01 EST (Wed, 06 Feb 2008)
@@ -628,6 +628,23 @@
>
{};
+The above transform serves to illustrate the behaviors of the _and_,
+_or_, and _not_ transforms, but it is admittedly contrived. The
+transform is more easily written as follows:
+
+ // Functionally identical to the UnwrapReference
+ // transform above:
+ struct UnwrapReference
+ : or_<
+ when<
+ terminal<reference_wrapper<_> >
+ , terminal<unwrap_reference<_arg> >(_arg)
+ >
+ , terminal<_>
+ , nary_expr<_, vararg<UnwrapReference> >
+ >
+ {};
+
[endsect]
[section:call [^call<>]]
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk