$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r51878 - in branches/release: . boost/proto boost/proto/transform libs/proto/doc/reference/transform libs/proto/test
From: eric_at_[hidden]
Date: 2009-03-20 19:22:19
Author: eric_niebler
Date: 2009-03-20 19:22:17 EDT (Fri, 20 Mar 2009)
New Revision: 51878
URL: http://svn.boost.org/trac/boost/changeset/51878
Log:
Merged revisions 51808,51821 via svnmerge from https://svn.boost.org/svn/boost/trunk
Added:
   branches/release/libs/proto/test/noinvoke.cpp
      - copied unchanged from r51821, /trunk/libs/proto/test/noinvoke.cpp
Properties modified: 
   branches/release/   (props changed)
Text files modified: 
   branches/release/boost/proto/make_expr.hpp                   |    22 +++++-----                              
   branches/release/boost/proto/proto_fwd.hpp                   |     3 +                                       
   branches/release/boost/proto/transform/make.hpp              |    22 ++++++++-                               
   branches/release/libs/proto/doc/reference/transform/make.xml |    83 +++++++++++++++++++++++++++++++++++++++ 
   branches/release/libs/proto/test/Jamfile.v2                  |     1                                         
   5 files changed, 114 insertions(+), 17 deletions(-)
Modified: branches/release/boost/proto/make_expr.hpp
==============================================================================
--- branches/release/boost/proto/make_expr.hpp	(original)
+++ branches/release/boost/proto/make_expr.hpp	2009-03-20 19:22:17 EDT (Fri, 20 Mar 2009)
@@ -721,7 +721,7 @@
         /// <tt>as_expr\<Domain\>(x)</tt>.
         ///
         /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
-        /// <tt>expr\<Tag, listN\<B0,...BN\> \>::::make(b0,...bN)</tt>
+        /// <tt>expr\<Tag, listN\<C0,...CN\> \>::::make(c0,...cN)</tt>
         /// where \c Bx is the type of \c bx.
         ///
         /// \return <tt>Domain()(make_\<Tag\>(wrap_(a0),...wrap_(aN)))</tt>.
@@ -744,19 +744,19 @@
 
         /// \overload
         ///
-        template<typename Tag, typename Domain, typename B0>
+        template<typename Tag, typename Domain, typename C0>
         typename result_of::make_expr<
             Tag
           , Domain
-          , B0 const
+          , C0 const
         >::type const
-        make_expr(B0 const &b0)
+        make_expr(C0 const &c0)
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-              , B0 const
-            >()(b0);
+              , C0 const
+            >()(c0);
         }
 
         // Additional overloads generated by the preprocessor...
@@ -1110,19 +1110,19 @@
 
         /// \overload
         ///
-        template<typename Tag, typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, typename B)>
+        template<typename Tag, typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, typename C)>
         typename result_of::make_expr<
             Tag
           , Domain
-            BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
+            BOOST_PP_ENUM_TRAILING_PARAMS(N, const C)
         >::type const
-        make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const B, &b))
+        make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const C, &c))
         {
             return proto::detail::make_expr_<
                 Tag
               , Domain
-                BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
-            >()(BOOST_PP_ENUM_PARAMS(N, b));
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, const C)
+            >()(BOOST_PP_ENUM_PARAMS(N, c));
         }
 
     #undef N
Modified: branches/release/boost/proto/proto_fwd.hpp
==============================================================================
--- branches/release/boost/proto/proto_fwd.hpp	(original)
+++ branches/release/boost/proto/proto_fwd.hpp	2009-03-20 19:22:17 EDT (Fri, 20 Mar 2009)
@@ -712,6 +712,9 @@
     template<typename PrimitiveTransform>
     struct protect;
 
+    template<typename T>
+    struct noinvoke;
+
     template<typename Fun>
     struct lazy;
 
Modified: branches/release/boost/proto/transform/make.hpp
==============================================================================
--- branches/release/boost/proto/transform/make.hpp	(original)
+++ branches/release/boost/proto/transform/make.hpp	2009-03-20 19:22:17 EDT (Fri, 20 Mar 2009)
@@ -292,6 +292,9 @@
                 typedef void not_applied_;
             };
 
+            #define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Data>
+            #define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type
+
             template<
                 template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R
                 BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
@@ -301,14 +304,25 @@
                 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
             >
               : nested_type_if<
-                    #define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Data>
-                    #define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type
                     R<BOOST_PP_ENUM(N, TMP1, ~)>
                   , typelist<BOOST_PP_ENUM(N, TMP0, ~) >
-                    #undef TMP0
-                    #undef TMP1
                 >
             {};
+
+            template<
+                template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+              , typename Expr, typename State, typename Data
+            >
+            struct make_<noinvoke<R<BOOST_PP_ENUM_PARAMS(N, A)> >, Expr, State, Data
+                BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
+            >
+            {
+                typedef R<BOOST_PP_ENUM(N, TMP1, ~)> type;
+            };
+
+            #undef TMP0
+            #undef TMP1
             #endif
 
             template<
Modified: branches/release/libs/proto/doc/reference/transform/make.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/transform/make.xml	(original)
+++ branches/release/libs/proto/doc/reference/transform/make.xml	2009-03-20 19:22:17 EDT (Fri, 20 Mar 2009)
@@ -13,6 +13,56 @@
   </para>
   <namespace name="boost">
     <namespace name="proto">
+      <struct name="noinvoke">
+        <template>
+          <template-type-parameter name="T"/>
+        </template>
+        <purpose>A type annotation in an <conceptname>ObjectTransform</conceptname> which instructs
+          Proto not to look for a nested <computeroutput>::type</computeroutput> within
+          <computeroutput>T</computeroutput> after type substitution.</purpose>
+        <description>
+          <para>
+            <conceptname>ObjectTransform</conceptname>s are evaluated by
+            <computeroutput><classname alt="proto::make">proto::make<></classname></computeroutput>,
+            which finds all nested transforms and replaces them with the result of their applications.
+            If any substitutions are performed, the result is first assumed to be a metafunction to be applied;
+            that is, Proto checks to see if the result has a nested <computeroutput>::type</computeroutput>
+            typedef. If it does, that becomes the result. The purpose of <computeroutput>proto::noinvoke<></computeroutput>
+            is to prevent Proto from looking for a nested <computeroutput>::type</computeroutput> typedef
+            in these situations.
+          </para>
+          <para>
+            Example:
+            <programlisting>struct Test
+  : <classname>proto::when</classname><
+        <classname>_</classname>
+      , proto::noinvoke<
+            // This remove_pointer invocation is bloked by noinvoke
+            boost::remove_pointer<
+                // This add_pointer invocation is *not* blocked by noinvoke
+                boost::add_pointer<<classname>_</classname>>
+            >
+        >()
+    >
+{};
+
+void test_noinvoke()
+{
+    typedef <classname>proto::terminal</classname><int>::type Int;
+    
+    BOOST_MPL_ASSERT((
+        boost::is_same<
+            boost::result_of<Test(Int)>::type
+          , boost::remove_pointer<Int *>
+        >
+    ));
+    
+    Int i = {42};
+    boost::remove_pointer<Int *> t = Test()(i);
+}</programlisting>
+          </para>
+        </description>
+      </struct>
       <struct name="protect">
         <template>
           <template-type-parameter name="PrimitiveTransform"/>
@@ -121,7 +171,6 @@
                 <computeroutput><classname>proto::make</classname><T>::impl<Expr, State, Data>::result_type</computeroutput> is
                 computed as follows:
               </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>,
@@ -143,7 +192,37 @@
                     </para>
                   </listitem>
                   <listitem>
-                    Otherwise, if <computeroutput>O</computeroutput> is a template like
+                    If <computeroutput>O</computeroutput> is a template like
+                    <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>
+                        <para>
+                          For each <computeroutput>i</computeroutput> in
+                          <computeroutput>[0,n]</computeroutput>, let <computeroutput>
+                            X<subscript>i</subscript>'
+                          </computeroutput> be
+                          <computeroutput>
+                            boost::result_of<<classname>proto::make</classname><X<subscript>i</subscript>>(Expr, State, Data)>::type
+                          </computeroutput>
+                          (which evaluates this procedure recursively). Note that a substitution took place. (In this case,
+                          Proto merely assumes that a substitution took place for the sake of compile-time efficiency. There
+                          would be no reason to use <computeroutput><classname>proto::noinvoke<></classname></computeroutput>
+                          otherwise.)
+                        </para>
+                      </listitem>
+                      <listitem>
+                        <para>
+                          The result type is
+                          <computeroutput>
+                            S<X<subscript>0</subscript>',...X<subscript>n</subscript>'>
+                          </computeroutput>.
+                        </para>
+                      </listitem>
+                    </itemizedlist>
+                  </listitem>
+                  <listitem>
+                    If <computeroutput>O</computeroutput> is a template like
                     <computeroutput>S<X<subscript>0</subscript>,...X<subscript>n</subscript>></computeroutput>,
                     then the result type is calculated as follows:
                     <itemizedlist>
Modified: branches/release/libs/proto/test/Jamfile.v2
==============================================================================
--- branches/release/libs/proto/test/Jamfile.v2	(original)
+++ branches/release/libs/proto/test/Jamfile.v2	2009-03-20 19:22:17 EDT (Fri, 20 Mar 2009)
@@ -29,6 +29,7 @@
         [ run proto_fusion_s.cpp ]
         [ run toy_spirit.cpp ]
         [ run toy_spirit2.cpp ]
+        [ run noinvoke.cpp ]
         [ compile bug2407.cpp ]
     ;