|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r57439 - in trunk/libs/proto/doc: . reference reference/context reference/transform
From: eric_at_[hidden]
Date: 2009-11-06 18:24:24
Author: eric_niebler
Date: 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
New Revision: 57439
URL: http://svn.boost.org/trac/boost/changeset/57439
Log:
better docs for proto::extends, fixes #2844
Text files modified:
trunk/libs/proto/doc/front_end.qbk | 4 +
trunk/libs/proto/doc/reference.xml | 10 ++--
trunk/libs/proto/doc/reference/context/default.xml | 8 +-
trunk/libs/proto/doc/reference/expr.xml | 11 ++++
trunk/libs/proto/doc/reference/extends.xml | 83 +++++++++++++++++++++++++++++++++++++--
trunk/libs/proto/doc/reference/transform/default.xml | 12 ++--
trunk/libs/proto/doc/reference/transform/pass_through.xml | 10 ++--
7 files changed, 110 insertions(+), 28 deletions(-)
Modified: trunk/libs/proto/doc/front_end.qbk
==============================================================================
--- trunk/libs/proto/doc/front_end.qbk (original)
+++ trunk/libs/proto/doc/front_end.qbk 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -347,6 +347,10 @@
We want calculator expressions to be function objects, so we have to define an `operator()` that takes and returns doubles. The `calculator<>` wrapper above does that with the help of the _extends_ template. The first template to _extends_ parameter is the expression type we are extending. The second is the type of the wrapped expression. The third parameter is the domain that this wrapper is associated with. A wrapper type like `calculator<>` that inherits from _extends_ behaves just like the expression type it has extended, with any additional behaviors you choose to give it.
+[note [*Why not just inherit from [^proto::expr<>]?]
+
+You might be thinking that this expression extension business is unnecessarily complicated. After all, isn't this why C++ supports inheritance? Why can't [^calculator<Expr>] just inherit from [^Expr] directly? The reason is because [^Expr], which presumably is an instantiation of _expr_, has expression template-building operator overloads that will be incorrect for derived types. They will store `*this` by reference to `proto::expr<>`, effectively slicing off any derived parts. _extends_ gives your derived types operator overloads that don't slice off your additional members.]
+
Although not strictly necessary in this case, we bring `extends<>::operator=` into scope with a `using` declaration. This is really only necessary if you want expressions like `_1 = 3` to create a lazily evaluated assignment. _extends_ defines the appropriate `operator=` for you, but the compiler-generated `calculator<>::operator=` will hide it unless you make it available with the `using` declaration.
Note that in the implementation of `calculator<>::operator()`, we evaluate the expression with the `calculator_context` we defined earlier. As we saw before, the context is what gives the operators their meaning. In the case of the calculator, the context is also what defines the meaning of the placeholder terminals.
Modified: trunk/libs/proto/doc/reference.xml
==============================================================================
--- trunk/libs/proto/doc/reference.xml (original)
+++ trunk/libs/proto/doc/reference.xml 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -487,6 +487,11 @@
</listitem>
<listitem>
<computeroutput>
+ <classname alt="boost::proto::nullary_expr">proto::nullary_expr</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
<classname alt="boost::proto::or_">proto::or_</classname>
</computeroutput>
</listitem>
@@ -802,11 +807,6 @@
</listitem>
<listitem>
<computeroutput>
- <classname alt="boost::proto::nullary_expr">proto::nullary_expr</classname>
- </computeroutput>
- </listitem>
- <listitem>
- <computeroutput>
<classname alt="boost::proto::tag::plus">proto::tag::plus</classname>
</computeroutput>
</listitem>
Modified: trunk/libs/proto/doc/reference/context/default.xml
==============================================================================
--- trunk/libs/proto/doc/reference/context/default.xml (original)
+++ trunk/libs/proto/doc/reference/context/default.xml 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -32,13 +32,13 @@
<purpose>For exposition only</purpose>
<type>typename Expr::tag_type</type>
</typedef>
- <data-member name="s_expr">
+ <data-member name="s_expr" specifiers="static">
<purpose>For exposition only</purpose>
- <type>static Expr &</type>
+ <type>Expr &</type>
</data-member>
- <data-member name="s_context">
+ <data-member name="s_context" specifiers="static">
<purpose>For exposition only</purpose>
- <type>static Context &</type>
+ <type>Context &</type>
</data-member>
<typedef name="result_type">
<type><emphasis>see-below</emphasis></type>
Modified: trunk/libs/proto/doc/reference/expr.xml
==============================================================================
--- trunk/libs/proto/doc/reference/expr.xml (original)
+++ trunk/libs/proto/doc/reference/expr.xml 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -103,8 +103,8 @@
<method-group name="public static functions">
<!-- make -->
- <method name="make">
- <type>static expr const</type>
+ <method name="make" specifiers="static">
+ <type>expr const</type>
<template>
<template-type-parameter name="A" pack="1"/>
</template>
@@ -310,6 +310,13 @@
<purpose>For each <replaceable>N</replaceable> in <replaceable>[0,max(Arity,1))</replaceable>.</purpose>
</data-member>
+ <data-member name="proto_arity_c" specifiers="static">
+ <type>const long</type>
+ <purpose>
+ <computeroutput>= Arity;</computeroutput>
+ </purpose>
+ </data-member>
+
</struct>
<!-- proto::unexpr -->
Modified: trunk/libs/proto/doc/reference/extends.xml
==============================================================================
--- trunk/libs/proto/doc/reference/extends.xml (original)
+++ trunk/libs/proto/doc/reference/extends.xml 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -44,6 +44,61 @@
</template-type-parameter>
</template>
<purpose>For adding behaviors to a Proto expression template.</purpose>
+ <description>
+ <para>
+ Use <computeroutput>proto::extends<></computeroutput> to give expressions in your
+ domain custom data members and member functions.
+ </para>
+ <para>
+ Conceptually, using <computeroutput>proto::extends<></computeroutput> is akin
+ to inheriting from <computeroutput><classname>proto::expr</classname><></computeroutput>
+ and adding your own members. Using <computeroutput>proto::extends<></computeroutput> is
+ generally preferrable to straight inheritance because the members that would be inherited from
+ <computeroutput><classname>proto::expr</classname><></computeroutput> would
+ be wrong; they would incorrectly slice off your additional members when building
+ larger expressions from smaller ones. <computeroutput>proto::extends<></computeroutput>
+ automatically gives your expression types the appropriate operator overloads that
+ preserve your domain-specific members when composing expression trees.
+ </para>
+ <para>
+ Expression extensions are typically defined as follows:
+ </para>
+ <para>
+ <programlisting>template< typename Expr >
+struct my_expr
+ : proto::extends<
+ Expr // The expression type we're extending
+ , my_expr< Expr > // The type we're defining
+ , my_domain // The domain associated with this expression extension
+ >
+{
+ typedef proto::extends< Expr, my_expr< Expr >, my_domain > base_type;
+
+ // An expression extension is constructed from the expression
+ // it is extending.
+ my_expr( Expr const & e = Expr() )
+ : base_type( e )
+ {}
+
+ // Unhide proto::extends::operator=
+ // (This is only necessary if a lazy assignment operator
+ // makes sense for your domain-specific language.)
+ using base_type::operator=;
+
+ /*
+ ... domain-specific members go here ...
+ */
+};</programlisting>
+ </para>
+ <para>
+ See also:
+ <itemizedlist>
+ <listitem>
+ <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </description>
<struct name="result">
<template>
<template-type-parameter name="Signature"/>
@@ -51,10 +106,12 @@
<typedef name="type">
<type><replaceable>unspecified</replaceable></type>
</typedef>
+ <description>
+ <para>So that <computeroutput>boost::result_of<></computeroutput>
+ can compute the return type of <computeroutput>proto::extends::operator()</computeroutput>.
+ </para>
+ </description>
</struct>
- <data-member name="proto_expr_">
- <type>Expr</type>
- </data-member>
<typedef name="proto_base_expr">
<type>typename Expr::proto_base_expr</type>
</typedef>
@@ -74,7 +131,7 @@
<type>typename proto_base_expr::proto_arity</type>
</typedef>
<typedef name="proto_childN">
- <purpose>For each <replaceable>N</replaceable> in <replaceable>[0,max(1,proto_arity::value))</replaceable></purpose>
+ <purpose>For each <replaceable>N</replaceable> in <replaceable>[0,max(1,proto_arity_c))</replaceable></purpose>
<type>typename proto_base_expr::proto_child<replaceable>N</replaceable></type>
</typedef>
@@ -92,11 +149,15 @@
</constructor>
<method-group name="public static functions">
- <method name="make">
- <type>static Derived const</type>
+ <method name="make" specifiers="static">
+ <type>Derived const</type>
<parameter name="expr">
<paramtype>Expr const &</paramtype>
</parameter>
+ <description>
+ <para>Construct an expression extension from the base expression.</para>
+ </description>
+ <return>Derived(expr)</return>
</method>
</method-group>
@@ -278,6 +339,16 @@
</method>
</method-group>
+ <data-member name="proto_expr_">
+ <type>Expr</type>
+ <purpose>For exposition only.</purpose>
+ </data-member>
+
+ <data-member name="proto_arity_c" specifiers="static">
+ <type>const long</type>
+ <purpose><computeroutput>= proto_base_expr::proto_arity_c;</computeroutput></purpose>
+ </data-member>
+
</struct>
</namespace>
Modified: trunk/libs/proto/doc/reference/transform/default.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/default.xml (original)
+++ trunk/libs/proto/doc/reference/transform/default.xml 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -35,17 +35,17 @@
<purpose>For exposition only</purpose>
<type>typename Expr::tag_type</type>
</typedef>
- <data-member name="s_expr">
+ <data-member name="s_expr" specifiers="static">
<purpose>For exposition only</purpose>
- <type>static Expr</type>
+ <type>Expr</type>
</data-member>
- <data-member name="s_state">
+ <data-member name="s_state" specifiers="static">
<purpose>For exposition only</purpose>
- <type>static State</type>
+ <type>State</type>
</data-member>
- <data-member name="s_data">
+ <data-member name="s_data" specifiers="static">
<purpose>For exposition only</purpose>
- <type>static Data</type>
+ <type>Data</type>
</data-member>
<typedef name="result_type">
<type><emphasis>see-below</emphasis></type>
Modified: trunk/libs/proto/doc/reference/transform/pass_through.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/pass_through.xml (original)
+++ trunk/libs/proto/doc/reference/transform/pass_through.xml 2009-11-06 18:24:22 EST (Fri, 06 Nov 2009)
@@ -20,11 +20,11 @@
Given a Grammar such as <computeroutput><classname>proto::plus</classname><T0, T1></computeroutput>,
an expression type that matches the grammar such as
<computeroutput><classname>proto::plus</classname><E0, E1>::type</computeroutput>, a state
- <computeroutput>S</computeroutput> and a data <computeroutput>V</computeroutput>, the result of applying
- the <computeroutput>proto::pass_through<plus<T0, T1> ></computeroutput> transform is:
- <programlisting>plus<
- boost::result_of<T0(E0, S, V)>::type,
- boost::result_of<T1(E1, S, V)>::type
+ <computeroutput>S</computeroutput> and a data <computeroutput>D</computeroutput>, the result of applying
+ the <computeroutput>proto::pass_through<<classname>proto::plus</classname><T0, T1> ></computeroutput>
+ transform is: <programlisting><classname>proto::plus</classname><
+ boost::result_of<T0(E0, S, D)>::type,
+ boost::result_of<T1(E1, S, D)>::type
>::type</programlisting>
</para>
<para>
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