$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r79465 - in trunk: boost/proto/transform/detail libs/proto/doc libs/proto/doc/reference libs/proto/doc/reference/transform
From: eric_at_[hidden]
Date: 2012-07-13 00:59:55
Author: eric_niebler
Date: 2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
New Revision: 79465
URL: http://svn.boost.org/trac/boost/changeset/79465
Log:
reference docs for pseudo-pack expansions in transforms
Text files modified: 
   trunk/boost/proto/transform/detail/call.hpp       |     2                                         
   trunk/boost/proto/transform/detail/pack.hpp       |     7 ++                                      
   trunk/libs/proto/doc/reference.xml                |     5 +                                       
   trunk/libs/proto/doc/reference/repeat.xml         |    36 ++++++------                            
   trunk/libs/proto/doc/reference/transform/call.xml |    28 ++++++++-                               
   trunk/libs/proto/doc/reference/transform/impl.xml |   113 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/proto/doc/reference/transform/lazy.xml |    24 +++++++-                                
   trunk/libs/proto/doc/reference/transform/make.xml |    40 ++++++++-----                           
   trunk/libs/proto/doc/reference/transform/when.xml |   108 ++++++++++++++++++++++++++++++++++++++  
   9 files changed, 321 insertions(+), 42 deletions(-)
Modified: trunk/boost/proto/transform/detail/call.hpp
==============================================================================
--- trunk/boost/proto/transform/detail/call.hpp	(original)
+++ trunk/boost/proto/transform/detail/call.hpp	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -93,7 +93,7 @@
         struct impl
           : call<
                 typename detail::expand_pattern<
-                    proto::arity_of<Expr>::value
+                    proto::arity_of<Expr>::value // BUGBUG this isn't right. Could be pack(_child), should use arity of child!
                   , BOOST_PP_CAT(A, BOOST_PP_DEC(N))
                   , detail::BOOST_PP_CAT(expand_pattern_rest_, BOOST_PP_DEC(N))<
                         Fun
Modified: trunk/boost/proto/transform/detail/pack.hpp
==============================================================================
--- trunk/boost/proto/transform/detail/pack.hpp	(original)
+++ trunk/boost/proto/transform/detail/pack.hpp	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -23,6 +23,7 @@
 #include <boost/preprocessor/iteration/iterate.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
 #include <boost/proto/proto_fwd.hpp>
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -52,6 +53,12 @@
         template<typename Tfx, typename T>
         struct expand_pattern_helper<Tfx, pack(T)>
         {
+            // BUGBUG fix me. See comment in transform/detail/call.hpp
+            BOOST_MPL_ASSERT_MSG(
+                (is_same<T, _>::value)
+              , PACK_EXPANSIONS_OF_EXPRESSIONS_OTHER_THAN_THE_CURRENT_NOT_YET_SUPPORTED
+              , (T)
+            );
             typedef Tfx type(T);
             typedef mpl::true_ applied;
         };
Modified: trunk/libs/proto/doc/reference.xml
==============================================================================
--- trunk/libs/proto/doc/reference.xml	(original)
+++ trunk/libs/proto/doc/reference.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -609,6 +609,11 @@
       </listitem>
       <listitem>
         <computeroutput>
+          <classname alt="boost::proto::pack">proto::pack</classname>
+        </computeroutput>
+      </listitem>
+      <listitem>
+        <computeroutput>
           <classname alt="boost::proto::pass_through">proto::pass_through</classname>
         </computeroutput>
       </listitem>
Modified: trunk/libs/proto/doc/reference/repeat.xml
==============================================================================
--- trunk/libs/proto/doc/reference/repeat.xml	(original)
+++ trunk/libs/proto/doc/reference/repeat.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -305,7 +305,7 @@
       Generates sequences like
       <computeroutput>
         typename A<subscript>0</subscript>,
-        typename A<subscript>1</subscript>, ...
+        typename A<subscript>1</subscript>, â¦
         typename A<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -318,7 +318,7 @@
         <computeroutput>BOOST_PROTO_typename_A(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>typename A<subscript>0</subscript>, typename A<subscript>1</subscript>, ... typename A<subscript>N-1</subscript></programlisting>
+        <programlisting>typename A<subscript>0</subscript>, typename A<subscript>1</subscript>, ⦠typename A<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -329,7 +329,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> const &,
-        A<subscript>1</subscript> const &, ...
+        A<subscript>1</subscript> const &, â¦
         A<subscript>N-1</subscript> const &
       </computeroutput>.
     </purpose>
@@ -342,7 +342,7 @@
         <computeroutput>BOOST_PROTO_A_const_ref(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>A<subscript>0</subscript> const &, A<subscript>1</subscript> const &, ... A<subscript>N-1</subscript> const &</programlisting>
+        <programlisting>A<subscript>0</subscript> const &, A<subscript>1</subscript> const &, ⦠A<subscript>N-1</subscript> const &</programlisting>
       </para>
     </description>
   </macro>
@@ -353,7 +353,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> &,
-        A<subscript>1</subscript> &, ...
+        A<subscript>1</subscript> &, â¦
         A<subscript>N-1</subscript> &
       </computeroutput>.
     </purpose>
@@ -366,7 +366,7 @@
         <computeroutput>BOOST_PROTO_A_ref(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>A<subscript>0</subscript> &, A<subscript>1</subscript> &, ... A<subscript>N-1</subscript> &</programlisting>
+        <programlisting>A<subscript>0</subscript> &, A<subscript>1</subscript> &, ⦠A<subscript>N-1</subscript> &</programlisting>
       </para>
     </description>
   </macro>
@@ -377,7 +377,7 @@
       Generates sequences like 
       <computeroutput>
         A<subscript>0</subscript>,
-        A<subscript>1</subscript>, ...
+        A<subscript>1</subscript>, â¦
         A<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -390,7 +390,7 @@
         <computeroutput>BOOST_PROTO_A(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>A<subscript>0</subscript>, A<subscript>1</subscript>, ... A<subscript>N-1</subscript></programlisting>
+        <programlisting>A<subscript>0</subscript>, A<subscript>1</subscript>, ⦠A<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -401,7 +401,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> const,
-        A<subscript>1</subscript> const, ...
+        A<subscript>1</subscript> const, â¦
         A<subscript>N-1</subscript> const
       </computeroutput>.
     </purpose>
@@ -414,7 +414,7 @@
         <computeroutput>BOOST_PROTO_A_const(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>A<subscript>0</subscript> const, A<subscript>1</subscript> const, ... A<subscript>N-1</subscript> const</programlisting>
+        <programlisting>A<subscript>0</subscript> const, A<subscript>1</subscript> const, ⦠A<subscript>N-1</subscript> const</programlisting>
       </para>
     </description>
   </macro>
@@ -425,7 +425,7 @@
       Generates sequences like 
       <computeroutput>
         A<subscript>0</subscript> const & a<subscript>0</subscript>,
-        A<subscript>1</subscript> const & a<subscript>1</subscript>, ...
+        A<subscript>1</subscript> const & a<subscript>1</subscript>, â¦
         A<subscript>N-1</subscript> const & a<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -438,7 +438,7 @@
         <computeroutput>BOOST_PROTO_A_const_ref_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>A<subscript>0</subscript> const & a<subscript>0</subscript>, A<subscript>1</subscript> const & a<subscript>1</subscript>, ... A<subscript>N-1</subscript> const & a<subscript>N-1</subscript></programlisting>
+        <programlisting>A<subscript>0</subscript> const & a<subscript>0</subscript>, A<subscript>1</subscript> const & a<subscript>1</subscript>, ⦠A<subscript>N-1</subscript> const & a<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -449,7 +449,7 @@
       Generates sequences like
       <computeroutput>
         A<subscript>0</subscript> & a<subscript>0</subscript>,
-        A<subscript>1</subscript> & a<subscript>1</subscript>, ...
+        A<subscript>1</subscript> & a<subscript>1</subscript>, â¦
         A<subscript>N-1</subscript> & a<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -462,7 +462,7 @@
         <computeroutput>BOOST_PROTO_A_ref_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>A<subscript>0</subscript> & a<subscript>0</subscript>, A<subscript>1</subscript> & a<subscript>1</subscript>, ... A<subscript>N-1</subscript> & a<subscript>N-1</subscript></programlisting>
+        <programlisting>A<subscript>0</subscript> & a<subscript>0</subscript>, A<subscript>1</subscript> & a<subscript>1</subscript>, ⦠A<subscript>N-1</subscript> & a<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
@@ -473,7 +473,7 @@
       Generates sequences like 
       <computeroutput>
         boost::ref(a<subscript>0</subscript>),
-        boost::ref(a<subscript>1</subscript>), ...
+        boost::ref(a<subscript>1</subscript>), â¦
         boost::ref(a<subscript>N-1</subscript>)
       </computeroutput>.
     </purpose>
@@ -486,7 +486,7 @@
         <computeroutput>BOOST_PROTO_ref_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>boost::ref(a<subscript>0</subscript>), boost::ref(a<subscript>1</subscript>), ... boost::ref(a<subscript>N-1</subscript>)</programlisting>
+        <programlisting>boost::ref(a<subscript>0</subscript>), boost::ref(a<subscript>1</subscript>), ⦠boost::ref(a<subscript>N-1</subscript>)</programlisting>
       </para>
     </description>
   </macro>
@@ -497,7 +497,7 @@
       Generates sequences like 
       <computeroutput>
         a<subscript>0</subscript>,
-        a<subscript>1</subscript>, ...
+        a<subscript>1</subscript>, â¦
         a<subscript>N-1</subscript>
       </computeroutput>.
     </purpose>
@@ -510,7 +510,7 @@
         <computeroutput>BOOST_PROTO_a(<replaceable>N</replaceable>)</computeroutput> generates sequences like:
       </para>
       <para>
-        <programlisting>a<subscript>0</subscript>, a<subscript>1</subscript>, ... a<subscript>N-1</subscript></programlisting>
+        <programlisting>a<subscript>0</subscript>, a<subscript>1</subscript>, ⦠a<subscript>N-1</subscript></programlisting>
       </para>
     </description>
   </macro>
Modified: trunk/libs/proto/doc/reference/transform/call.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/call.xml	(original)
+++ trunk/libs/proto/doc/reference/transform/call.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -105,15 +105,26 @@
                   <listitem>
                     <para>
                       If <computeroutput>T</computeroutput> is of the form
-                      <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then
+                      <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>, then
                       <computeroutput>result_type</computeroutput> is:
                       <programlisting>typename boost::result_of<PolymorphicFunctionObject(
   typename boost::result_of<<classname>when</classname><<classname>_</classname>,A<subscript>0</subscript>>(Expr, State, Data)>::type,
-  ...
+  â¦
   typename boost::result_of<<classname>when</classname><<classname>_</classname>,A<subscript>n</subscript>>(Expr, State, Data)>::type
 >::type</programlisting>
                     </para>
                   </listitem>
+                  <listitem>
+                    <para>
+                      If <computeroutput>T</computeroutput> is of the form
+                      <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>, then
+                      let <computeroutput>T'</computeroutput> be <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,â¦A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
+                      where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
+                      as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>.
+                      Then, <computeroutput>result_type</computeroutput> is:
+                      <programlisting><computeroutput>typename <classname>proto::call</classname><T'>::impl<Expr,State,Data>::result_type</computeroutput></programlisting>
+                    </para>
+                  </listitem>
                 </itemizedlist>
               </para>
             </description>
@@ -188,7 +199,7 @@
                     <listitem>
                       <para>
                         If <computeroutput>T</computeroutput> is of the form
-                        <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then
+                        <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>, then
                         return:
                         <programlisting>PolymorphicFunctionObject()(
   <classname>when</classname><<classname>_</classname>,A<subscript>0</subscript>>()(expr, state, data),
@@ -197,6 +208,17 @@
 )</programlisting>
                       </para>
                     </listitem>
+                  <listitem>
+                    <para>
+                      If <computeroutput>T</computeroutput> is of the form
+                      <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>, then
+                      let <computeroutput>T'</computeroutput> be <computeroutput><conceptname>PolymorphicFunctionObject</conceptname>(A<subscript>0</subscript>,â¦A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
+                      where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
+                      as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>.
+                      Then, return:
+                      <programlisting><computeroutput><classname>proto::call</classname><T'>()(expr, state, data)</computeroutput></programlisting>
+                    </para>
+                  </listitem>
                   </itemizedlist>
                 </para>
               </description>
Modified: trunk/libs/proto/doc/reference/transform/impl.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/impl.xml	(original)
+++ trunk/libs/proto/doc/reference/transform/impl.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -183,6 +183,119 @@
           <type>typename boost::add_reference<Data const>::type</type>
         </typedef>
       </struct>
+
+      <!-- proto::pack -->
+      <struct name="pack">
+
+        <purpose>To turn an expression into a pseudo-parameter pack containing the
+        expression's children, for the purpose of expanding the pack expression within
+        a <conceptname>CallableTransform</conceptname> or
+        <conceptname>ObjectTransform</conceptname>.</purpose>
+
+        <description>
+          <para>
+            <computeroutput>proto::pack</computeroutput> is useful within
+            <conceptname>CallableTransform</conceptname>s and
+            <conceptname>ObjectTransform</conceptname>s when one wishes to unpack an expression
+            into a function call or an object constructor. <computeroutput>proto::pack</computeroutput>
+            turns a Proto expression into a pseudo-parameter pack, which may appear in an unpacking
+            pattern to be expanded with the "<computeroutput>...</computeroutput>" syntax.
+          </para>
+
+          <para>
+            <emphasis role="bold">Example:</emphasis>
+          </para>
+
+          <para>
+            <programlisting>// The following demonstrates how to use a pseudo-pack expansion
+// to unpack an expression into a function call.
+
+struct do_sum : <classname alt="boost::proto::callable">proto::callable</classname>
+{
+    typedef int result_type;
+    
+    int operator()(int i) const { return i; }
+    int operator()(int i, int j) const { return i + j; }
+    int operator()(int i, int j, int k) const { return i + j + k; }
+};
+
+// Take any n-ary expression where the children are all int terminals and sum all the ints
+struct sum
+  : <classname alt="boost::proto::when">proto::when</classname><
+  
+        // Match any nary expression where the children are all int terminals
+        <classname alt="boost::proto::nary_expr">proto::nary_expr</classname><<classname alt="boost::proto::_">_</classname>, <classname alt="boost::proto::vararg">proto::vararg</classname><<classname alt="boost::proto::terminal">proto::terminal</classname><int> > >
+
+        // Turn the current expression into a pseudo-parameter pack, then expand it,
+        // extracting the value from each child in turn.
+      , do_sum(<classname alt="boost::proto::_value">proto::_value</classname>(proto::pack(<classname alt="boost::proto::_">_</classname>))...)
+    >
+{};
+
+int main()
+{
+    <classname alt="boost::proto::terminal">proto::terminal</classname><int>::type i = {42};
+    int result = sum()( i(3,5) ); // Creates a ternary functional-call expression
+    std::cout << "Sum of 42, 3, and 5 : " << result << std::endl;
+}</programlisting>
+          </para>
+
+          <para>
+            The above program displays:
+          </para>
+
+          <para>
+            <computeroutput>Sum of 42, 3, and 5 : 50</computeroutput>
+          </para>
+
+          <para>
+            <emphasis role="bold">Unpacking Patterns:</emphasis>
+          </para>
+
+          <para>
+            Composite transforms (either <conceptname>CallableTransform</conceptname>s or
+            <conceptname>ObjectTransform</conceptname>s) usually have the form
+            <computeroutput>X(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>.
+            However, when the argument list in a composite transform is terminated with a C-style
+            vararg ellipsis as in <computeroutput>X(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>,
+            the final argument <computeroutput>A<subscript>n</subscript></computeroutput> is treated
+            as an <emphasis>unpacking expression</emphasis>.
+          </para>
+          
+          <para>
+            An unpacking expression must itself be a composite transform; that is, it must be a
+            function type representing either a <conceptname>CallableTransform</conceptname> or
+            an <conceptname>ObjectTransform</conceptname>. The type <computeroutput>proto::pack(_)</computeroutput>
+            must appear exactly once in the unpacking expression. This type will receive a substitution
+            when the unpacking expression is expanded.
+          </para>
+
+          <para>
+            A composite transform like <computeroutput>X(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>,
+            when evaluated against a given expression <replaceable>E</replaceable>, state and data, is evaluated as if it were
+            <computeroutput>X(A<subscript>0</subscript>,â¦A<subscript>n-1</subscript>,<replaceable>S</replaceable>)</computeroutput>
+            where <replaceable>S</replaceable> is a type sequence computed as follows:
+          </para>
+          <para>
+            Let <computeroutput><replaceable>SUB</replaceable>(A,B)</computeroutput> be a type function that replaces every occurence of
+            <computeroutput>proto::pack(_)</computeroutput> within <computeroutput>A</computeroutput> with <computeroutput>B</computeroutput>.
+            <itemizedlist>
+              <listitem>
+                If the expression <replaceable>E</replaceable> is a terminal (i.e. it has arity 0), <replaceable>S</replaceable>
+                is the one-element sequence containing <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_value">proto::_value</classname>)</computeroutput>.
+              </listitem>
+              <listitem>
+                If the expression <replaceable>E</replaceable> is a non-terminal, <replaceable>S</replaceable> is the sequence
+                <computeroutput><replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><0>),â¦
+                <replaceable>SUB</replaceable>(A<subscript>n</subscript>, <classname alt="boost::proto::_child_c">proto::_child_c</classname><<replaceable>M</replaceable>-1>)</computeroutput>, where
+                <replaceable>M</replaceable> is the arity of the expression <replaceable>E</replaceable>.
+              </listitem>
+            </itemizedlist>
+          </para>
+        </description>
+
+        </struct>
+      
     </namespace>
   </namespace>
 </header>
Modified: trunk/libs/proto/doc/reference/transform/lazy.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/lazy.xml	(original)
+++ trunk/libs/proto/doc/reference/transform/lazy.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -64,9 +64,17 @@
                   <listitem>
                     <para>
                       If <computeroutput>T</computeroutput> if of the form
-                      <computeroutput>O(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
+                      <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
                       be <computeroutput>boost::result_of<<classname>proto::make</classname><O>(Expr, State, Data)>::type</computeroutput>
-                      and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>.
+                      and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>.
+                    </para>
+                  </listitem>
+                  <listitem>
+                    <para>
+                      If <computeroutput>T</computeroutput> if of the form
+                      <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>, then let <computeroutput>O'</computeroutput>
+                      be <computeroutput>boost::result_of<<classname>proto::make</classname><O>(Expr, State, Data)>::type</computeroutput>
+                      and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>.
                     </para>
                   </listitem>
                   <listitem>
@@ -104,9 +112,17 @@
                     <listitem>
                       <para>
                         If <computeroutput>T</computeroutput> if of the form
-                        <computeroutput>O(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
+                        <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>, then let <computeroutput>O'</computeroutput>
+                        be <computeroutput>boost::result_of<<classname>proto::make</classname><O>(Expr, State, Data)>::type</computeroutput>
+                        and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>.
+                      </para>
+                    </listitem>
+                    <listitem>
+                      <para>
+                        If <computeroutput>T</computeroutput> if of the form
+                        <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>, then let <computeroutput>O'</computeroutput>
                         be <computeroutput>boost::result_of<<classname>proto::make</classname><O>(Expr, State, Data)>::type</computeroutput>
-                        and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>.
+                        and let <computeroutput>T'</computeroutput> be <computeroutput>O'(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>.
                       </para>
                     </listitem>
                     <listitem>
Modified: trunk/libs/proto/doc/reference/transform/make.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/make.xml	(original)
+++ trunk/libs/proto/doc/reference/transform/make.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -149,9 +149,7 @@
           <para>
             The purpose of <computeroutput>proto::make<></computeroutput> is to annotate a transform as
             an <conceptname>ObjectTransform</conceptname> so that
-            <computeroutput>
-              <classname alt="proto::when">proto::when<></classname>
-            </computeroutput> knows
+            <computeroutput><classname alt="proto::when">proto::when<></classname></computeroutput> knows
             how to apply it.
           </para>
 
@@ -180,7 +178,8 @@
               </para>
               <para>
                 If <computeroutput>T</computeroutput> is an <conceptname>ObjectTransform</conceptname> of the form
-                <computeroutput>Object(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>,
+                <computeroutput>Object(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput> or
+                <computeroutput>Object(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>,
                 then let <computeroutput>O</computeroutput> be the return type
                 <computeroutput>Object</computeroutput>. Otherwise, let <computeroutput>O</computeroutput>
                 be <computeroutput>T</computeroutput>. The <computeroutput>result_type</computeroutput> typedef is
@@ -200,7 +199,7 @@
                   </listitem>
                   <listitem>
                     If <computeroutput>O</computeroutput> is a template like
-                    <computeroutput><classname>proto::noinvoke</classname><S<X<subscript>0</subscript>,...X<subscript>n</subscript>> ></computeroutput>,
+                    <computeroutput><classname>proto::noinvoke</classname><S<X<subscript>0</subscript>,â¦X<subscript>n</subscript>> ></computeroutput>,
                     then the result type is calculated as follows:
                     <itemizedlist>
                       <listitem>
@@ -222,7 +221,7 @@
                         <para>
                           The result type is
                           <computeroutput>
-                            S<X<subscript>0</subscript>',...X<subscript>n</subscript>'>
+                            S<X<subscript>0</subscript>',â¦X<subscript>n</subscript>'>
                           </computeroutput>.
                         </para>
                       </listitem>
@@ -230,7 +229,7 @@
                   </listitem>
                   <listitem>
                     If <computeroutput>O</computeroutput> is a template like
-                    <computeroutput>S<X<subscript>0</subscript>,...X<subscript>n</subscript>></computeroutput>,
+                    <computeroutput>S<X<subscript>0</subscript>,â¦X<subscript>n</subscript>></computeroutput>,
                     then the result type is calculated as follows:
                     <itemizedlist>
                       <listitem>
@@ -250,11 +249,11 @@
                         <para>
                           If any substitutions took place in the above step and
                           <computeroutput>
-                            S<X<subscript>0</subscript>',...X<subscript>n</subscript>'>
+                            S<X<subscript>0</subscript>',â¦X<subscript>n</subscript>'>
                           </computeroutput> has a nested
                           <computeroutput>type</computeroutput> typedef, the result type is
                           <computeroutput>
-                            S<X<subscript>0</subscript>',...X<subscript>n</subscript>'>::type
+                            S<X<subscript>0</subscript>',â¦X<subscript>n</subscript>'>::type
                           </computeroutput>.
                         </para>
                       </listitem>
@@ -262,7 +261,7 @@
                         <para>
                           Otherwise, the result type is
                           <computeroutput>
-                            S<X<subscript>0</subscript>',...X<subscript>n</subscript>'>
+                            S<X<subscript>0</subscript>',â¦X<subscript>n</subscript>'>
                           </computeroutput>.
                         </para>
                       </listitem>
@@ -306,7 +305,7 @@
                     <listitem>
                       <para>
                         If <computeroutput>T</computeroutput> is of the form
-                        <computeroutput>O(A<subscript>0</subscript>,...A<subscript>n</subscript>)</computeroutput>, then:
+                        <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n</subscript>)</computeroutput>, then:
                       </para>
                       <itemizedlist>
                         <listitem>
@@ -317,7 +316,7 @@
                             and return an object <computeroutput>that</computeroutput> as follows:
                             <programlisting>result_type that = {
   <classname>proto::when</classname><<classname>_</classname>, A<subscript>0</subscript>>()(expr, state, data),
-  ...
+  â¦
   <classname>proto::when</classname><<classname>_</classname>, A<subscript>n</subscript>>()(expr, state, data)
 };</programlisting>
                           </para>
@@ -328,7 +327,7 @@
                             and return an object <computeroutput>that</computeroutput> as follows:
                             <programlisting>result_type that(
   <classname>proto::when</classname><<classname>_</classname>, A<subscript>0</subscript>>()(expr, state, data),
-  ...
+  â¦
   <classname>proto::when</classname><<classname>_</classname>, A<subscript>n</subscript>>()(expr, state, data)
 );</programlisting>
                           </para>
@@ -337,9 +336,18 @@
                     </listitem>
                     <listitem>
                       <para>
-                        Otherwise, construct
-                        and return an object <computeroutput>that</computeroutput> as follows:
-                        <programlisting>result_type that = result_type();</programlisting>
+                        If <computeroutput>T</computeroutput> is of the form
+                        <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n</subscript> ...)</computeroutput>,
+                        then let <computeroutput>T'</computeroutput> be <computeroutput>O(A<subscript>0</subscript>,â¦A<subscript>n-1</subscript>, <replaceable>S</replaceable>)</computeroutput>,
+                        where <replaceable>S</replaceable> is a type sequence computed from the unpacking expression <computeroutput>A<subscript>n</subscript></computeroutput>
+                        as described in the reference for <computeroutput><classname>proto::pack</classname></computeroutput>. Then, return:
+                        <programlisting>proto::make<T'>()(expr, state, data)</programlisting>
+                      </para>
+                    </listitem>
+                    <listitem>
+                      <para>
+                        Otherwise, construct and return an object <computeroutput>that</computeroutput>
+                        as follows: <programlisting>result_type that = result_type();</programlisting>
                       </para>
                     </listitem>
                   </itemizedlist>
Modified: trunk/libs/proto/doc/reference/transform/when.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/when.xml	(original)
+++ trunk/libs/proto/doc/reference/transform/when.xml	2012-07-13 00:59:53 EDT (Fri, 13 Jul 2012)
@@ -199,6 +199,114 @@
       <struct-specialization name="when">
         <template>
           <template-type-parameter name="Grammar"/>
+          <template-type-parameter name="R"/>
+          <template-type-parameter name="A" pack="1"/>
+        </template>
+        <specialization>
+          <template-arg>Grammar</template-arg>
+          <template-arg>R(A..., ...)</template-arg>
+        </specialization>
+        <inherit><type><classname>proto::transform</classname>< when<Grammar, R(A..., ...)> ></type></inherit>
+        <purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a
+          transform with the grammar. </purpose>
+        <description>
+          <para>
+            Use <computeroutput>proto::when<></computeroutput> to override a grammar's default
+            transform with a custom transform. It is for use when composing larger transforms by associating
+            smaller transforms with individual rules in your grammar.
+          </para>
+          <para>
+            The <computeroutput>when<G, R(A..., ...)></computeroutput> form accepts either a
+            <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its
+            second parameter. <computeroutput>proto::when<></computeroutput> uses
+            <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> to
+            distinguish between the two, and uses
+            <computeroutput><classname>proto::call<></classname></computeroutput> to evaluate
+            <conceptname>CallableTransform</conceptname>s and
+            <computeroutput><classname>proto::make<></classname></computeroutput> to evaluate
+            <conceptname>ObjectTransform</conceptname>s.
+          </para>
+          <para>
+            <emphasis role="bold">Note:</emphasis> In the specialization
+            <computeroutput>when<G, R(A..., ...)></computeroutput>, the first ellipsis denotes a
+            C++11-style variadic template (which is emulated for C++98 compilers). The second ellipsis
+            is a C-style vararg.
+          </para>
+        </description>
+        <struct name="impl">
+          <template>
+            <template-type-parameter name="Expr"/>
+            <template-type-parameter name="State"/>
+            <template-type-parameter name="Data"/>
+          </template>
+          <inherit><type><classname>proto::transform_impl</classname>< Expr, State, Data ></type></inherit>
+          <typedef name="call_">
+            <purpose>For exposition only</purpose>
+            <type><classname>proto::call</classname><R(A..., ...)></type>
+          </typedef>
+          <typedef name="make_">
+            <purpose>For exposition only</purpose>
+            <type><classname>proto::make</classname><R(A..., ...)></type>
+          </typedef>
+          <typedef name="which">
+            <purpose>For exposition only</purpose>
+            <type>typename mpl::if_<<classname>proto::is_callable</classname><R>,call_,make_>::type</type>
+          </typedef>
+          <typedef name="result_type">
+            <type>typename boost::result_of<which(Expr, State, Data)>::type</type>
+          </typedef>
+          <method-group name="public member functions">
+            <method name="operator()" cv="const">
+              <type>result_type</type>
+              <parameter name="expr">
+                <paramtype>typename impl::expr_param</paramtype>
+                <description>
+                  <para>The current expression </para>
+                </description>
+              </parameter>
+              <parameter name="state">
+                <paramtype>typename impl::state_param</paramtype>
+                <description>
+                  <para>The current state </para>
+                </description>
+              </parameter>
+              <parameter name="data">
+                <paramtype>typename impl::data_param</paramtype>
+                <description>
+                  <para>An arbitrary data </para>
+                </description>
+              </parameter>
+              <description>
+                <para>
+                  Evaluate <computeroutput>R(A..., ...)</computeroutput> as a transform either with
+                  <computeroutput><classname>proto::call<></classname></computeroutput> or with
+                  <computeroutput><classname>proto::make<></classname></computeroutput> depending
+                  on whether <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput>
+                  is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.
+                </para>
+              </description>
+              <requires>
+                <para>
+                  <computeroutput><classname>proto::matches</classname><Expr, Grammar>::value</computeroutput>
+                  is <computeroutput>true</computeroutput>.
+                </para>
+              </requires>
+              <returns>
+                <para>
+                  <computeroutput>which()(expr, state, data)</computeroutput>
+                </para>
+              </returns>
+            </method>
+          </method-group>
+        </struct>
+        <typedef name="proto_grammar">
+          <type>typename Grammar::proto_grammar</type>
+        </typedef>
+      </struct-specialization>
+
+      <struct-specialization name="when">
+        <template>
+          <template-type-parameter name="Grammar"/>
         </template>
         <specialization>
           <template-arg>Grammar</template-arg>