Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66990 - in trunk: boost/proto/transform libs/proto/doc libs/proto/doc/reference libs/proto/doc/reference/transform
From: eric_at_[hidden]
Date: 2010-12-03 17:10:38


Author: eric_niebler
Date: 2010-12-03 17:10:14 EST (Fri, 03 Dec 2010)
New Revision: 66990
URL: http://svn.boost.org/trac/boost/changeset/66990

Log:
ah! the REAL fix for the long-standing proto::make bug
Text files modified:
   trunk/boost/proto/transform/make.hpp | 52 ++++++-------------
   trunk/libs/proto/doc/reference.xml | 5 +
   trunk/libs/proto/doc/reference/traits.xml | 46 +++++++++++++++++
   trunk/libs/proto/doc/reference/transform/call.xml | 104 ++++++++++++++++++++++-----------------
   trunk/libs/proto/doc/reference/transform/make.xml | 20 +++---
   5 files changed, 137 insertions(+), 90 deletions(-)

Modified: trunk/boost/proto/transform/make.hpp
==============================================================================
--- trunk/boost/proto/transform/make.hpp (original)
+++ trunk/boost/proto/transform/make.hpp 2010-12-03 17:10:14 EST (Fri, 03 Dec 2010)
@@ -61,41 +61,19 @@
             {};
 
             template<typename R, typename Expr, typename State, typename Data
- BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
+ , bool IsTransform = is_transform<R>::value
>
- struct make_
+ struct make_if_
             {
                 typedef R type;
                 typedef void not_applied_;
             };
 
- template<typename R, typename Expr, typename State, typename Data
- , bool IsTransform = is_transform<R>::value
- >
- struct make_if2_
- : make_<R, Expr, State, Data>
- {};
-
             template<typename R, typename Expr, typename State, typename Data>
- struct make_if2_<R, Expr, State, Data, true>
+ struct make_if_<R, Expr, State, Data, true>
               : uncvref<typename R::template impl<Expr, State, Data>::result_type>
             {};
 
- template<typename R, typename Expr, typename State, typename Data
- // HACKHACK This should really be is_transform; however, is_transform
- // would have the unfortunate side-effect of instantiating R which is
- // not acceptable in this context. Instead, we first check to see if
- // R is callable, which will not instantiate R. If is_callable is true,
- // it is safe to instantiate R to check if it is a transform.
- , bool IsCallable = is_callable<R>::value
- >
- struct make_if_;
-
- template<typename R, typename Expr, typename State, typename Data>
- struct make_if_<R, Expr, State, Data, false>
- : make_<R, Expr, State, Data>
- {};
-
             #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
             // work around GCC bug
             template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
@@ -114,9 +92,11 @@
             };
             #endif
 
- template<typename R, typename Expr, typename State, typename Data>
- struct make_if_<R, Expr, State, Data, true>
- : make_if2_<R, Expr, State, Data>
+ template<typename R, typename Expr, typename State, typename Data
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
+ >
+ struct make_
+ : make_if_<R, Expr, State, Data>
             {};
 
             template<typename Type, bool IsAggregate = is_aggregate<Type>::value>
@@ -229,7 +209,7 @@
         ///
         /// \li Function types
         /// \li Function pointer types
- /// \li Types for which <tt>proto::is_callable\< type \>::value</tt> is \c true
+ /// \li Types for which <tt>proto::is_transform\< type \>::value</tt> is \c true
         ///
         /// <tt>boost::result_of\<make\<T\<X0,X1,...\> \>(Expr, State, Data)\>::type</tt>
         /// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
@@ -256,7 +236,7 @@
             template<typename Expr, typename State, typename Data>
             struct impl : transform_impl<Expr, State, Data>
             {
- typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
+ typedef typename detail::make_<Object, Expr, State, Data>::type result_type;
 
                 /// \return <tt>result_type()</tt>
                 result_type operator ()(
@@ -311,7 +291,7 @@
                 typedef void not_applied_;
             };
 
- #define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Data>
+ #define TMP0(Z, M, DATA) make_<BOOST_PP_CAT(A, M), Expr, State, Data>
             #define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type
 
             template<
@@ -349,7 +329,9 @@
                 BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
               , typename Expr, typename State, typename Data
>
- struct make_if_<R(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
+ struct make_<R(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)
+ >
             {
                 typedef
                     typename uncvref<
@@ -364,7 +346,9 @@
                 BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
               , typename Expr, typename State, typename Data
>
- struct make_if_<R(*)(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
+ struct make_<R(*)(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)
+ >
             {
                 typedef
                     typename uncvref<
@@ -411,7 +395,7 @@
             struct impl : transform_impl<Expr, State, Data>
             {
                 /// \brief <tt>boost::result_of\<make\<Object\>(Expr, State, Data)\>::type</tt>
- typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
+ typedef typename detail::make_<Object, Expr, State, Data>::type result_type;
 
                 /// Let \c ax be <tt>when\<_, Ax\>()(e, s, d)</tt>
                 /// for each \c x in <tt>[0,N]</tt>.

Modified: trunk/libs/proto/doc/reference.xml
==============================================================================
--- trunk/libs/proto/doc/reference.xml (original)
+++ trunk/libs/proto/doc/reference.xml 2010-12-03 17:10:14 EST (Fri, 03 Dec 2010)
@@ -442,6 +442,11 @@
       </listitem>
       <listitem>
         <computeroutput>
+ <classname alt="boost::proto::is_transform">proto::is_transform</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
           <classname alt="boost::proto::lazy">proto::lazy</classname>
         </computeroutput>
       </listitem>

Modified: trunk/libs/proto/doc/reference/traits.xml
==============================================================================
--- trunk/libs/proto/doc/reference/traits.xml (original)
+++ trunk/libs/proto/doc/reference/traits.xml 2010-12-03 17:10:14 EST (Fri, 03 Dec 2010)
@@ -16,6 +16,7 @@
   </para>
   <namespace name="boost">
     <namespace name="proto">
+
       <struct name="is_callable">
         <template>
           <template-type-parameter name="T"/>
@@ -66,6 +67,51 @@
         <inherit><type>mpl::bool_&lt;<replaceable>true-or-false</replaceable>&gt;</type></inherit>
       </struct>
 
+ <struct name="is_transform">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <purpose>Boolean metafunction which tells whether a type is a
+ <conceptname>PrimitiveTransform</conceptname> or not.</purpose>
+ <description>
+ <para>
+ <computeroutput>proto::is_transform&lt;&gt;</computeroutput> is used by the
+ <computeroutput><classname alt="proto::make">proto::make&lt;&gt;</classname></computeroutput>
+ transform to determine whether a type <computeroutput>R</computeroutput> represents a
+ <conceptname>PrimitiveTransform</conceptname> to apply, or whether it merely represents itself.
+ </para>
+ <para>
+ It is also used by the
+ <computeroutput><classname alt="proto::call">proto::call&lt;&gt;</classname></computeroutput>
+ transform to determine whether the function types <computeroutput>R()</computeroutput>,
+ <computeroutput>R(A1)</computeroutput>, and <computeroutput>R(A1, A2)</computeroutput> should
+ be passed the expression, state and data parameters (as needed).
+ </para>
+ <para>
+ Unless specialized for a type
+ <computeroutput>T</computeroutput>, <computeroutput>proto::is_transform&lt;T&gt;::value</computeroutput>
+ is computed as follows:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> is a class type that inherits directly or indirectly from
+ an instantiation of
+ <computeroutput><classname alt="proto::transform">proto::transform&lt;&gt;</classname></computeroutput>,
+ <computeroutput>proto::is_transform&lt;T&gt;::value</computeroutput> is <computeroutput>true</computeroutput>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, <computeroutput>proto::is_transform&lt;T&gt;::value</computeroutput>
+ is <computeroutput>false</computeroutput>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </description>
+ <inherit><type>mpl::bool_&lt;<replaceable>true-or-false</replaceable>&gt;</type></inherit>
+ </struct>
+
       <struct name="is_aggregate">
         <template>
           <template-type-parameter name="T"/>

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 2010-12-03 17:10:14 EST (Fri, 03 Dec 2010)
@@ -41,6 +41,12 @@
             <type><replaceable>see-below</replaceable></type>
             <description>
               <para>
+ In the description that follows, a type <computeroutput>T</computeroutput> is determined to model the
+ <conceptname>PrimitiveTransform</conceptname> concept if
+ <computeroutput><classname>proto::is_transform</classname>&lt;T&gt;::value</computeroutput> is
+ <computeroutput>true</computeroutput>.
+ </para>
+ <para>
                 <computeroutput><classname>proto::call</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::result_type</computeroutput>
                 is computed as follows:
                 <itemizedlist>
@@ -118,68 +124,74 @@
                 <paramtype>typename impl::data_param</paramtype>
               </parameter>
               <description>
- <para>
- <computeroutput><classname>proto::call</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()</computeroutput> behaves as follows:
- <itemizedlist>
- <listitem>
- <para>
- If <computeroutput>T</computeroutput> if of the form
- <computeroutput><conceptname>PrimitiveTransform</conceptname></computeroutput> or
- <computeroutput><conceptname>PrimitiveTransform</conceptname>()</computeroutput>, then
- return
- <programlisting>PrimitiveTransform()(expr, state, data)</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- If <computeroutput>T</computeroutput> is of the form
- <computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>)</computeroutput>, then
- return
- <programlisting>PrimitiveTransform()(
+ <para>
+ In the description that follows, a type <computeroutput>T</computeroutput> is determined to model the
+ <conceptname>PrimitiveTransform</conceptname> concept if
+ <computeroutput><classname>proto::is_transform</classname>&lt;T&gt;::value</computeroutput> is
+ <computeroutput>true</computeroutput>.
+ </para>
+ <para>
+ <computeroutput><classname>proto::call</classname>&lt;T&gt;::impl&lt;Expr,State,Data&gt;::operator()</computeroutput> behaves as follows:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> if of the form
+ <computeroutput><conceptname>PrimitiveTransform</conceptname></computeroutput> or
+ <computeroutput><conceptname>PrimitiveTransform</conceptname>()</computeroutput>, then
+ return
+ <programlisting>PrimitiveTransform()(expr, state, data)</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> is of the form
+ <computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>)</computeroutput>, then
+ return
+ <programlisting>PrimitiveTransform()(
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
   state,
   sata
 )</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- If <computeroutput>T</computeroutput> is of the form
- <computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>)</computeroutput>, then
- return:
- <programlisting>PrimitiveTransform()(
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> is of the form
+ <computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>)</computeroutput>, then
+ return:
+ <programlisting>PrimitiveTransform()(
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>1</subscript>&gt;()(expr, state, data),
   Data
 )</programlisting>
- </para>
- </listitem>
- <listitem>
- <para>
- If <computeroutput>T</computeroutput> is of the form
- <computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>, A<subscript>2</subscript>)</computeroutput>, then
- return
- <programlisting>PrimitiveTransform()(
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <computeroutput>T</computeroutput> is of the form
+ <computeroutput><conceptname>PrimitiveTransform</conceptname>(A<subscript>0</subscript>, A<subscript>1</subscript>, A<subscript>2</subscript>)</computeroutput>, then
+ return
+ <programlisting>PrimitiveTransform()(
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>1</subscript>&gt;()(expr, state, data),
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>2</subscript>&gt;()(expr, state, data)
 )</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
- return:
- <programlisting>PolymorphicFunctionObject()(
+ </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
+ return:
+ <programlisting>PolymorphicFunctionObject()(
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>0</subscript>&gt;()(expr, state, data),
   ...
   <classname>when</classname>&lt;<classname>_</classname>,A<subscript>n</subscript>&gt;()(expr, state, data)
 )</programlisting>
- </para>
- </listitem>
- </itemizedlist>
- </para>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
               </description>
             </method>
           </method-group>

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 2010-12-03 17:10:14 EST (Fri, 03 Dec 2010)
@@ -182,16 +182,6 @@
               <para>
                 <itemizedlist>
                   <listitem>
- <para>
- If <computeroutput>O</computeroutput> is a <conceptname>Transform</conceptname>, then let
- the result type be
- <computeroutput>
- boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>_</classname>, O&gt;(Expr, State, Data)&gt;::type
- </computeroutput>.
- Note that a substitution took place.
- </para>
- </listitem>
- <listitem>
                     If <computeroutput>O</computeroutput> is a template like
                     <computeroutput><classname>proto::noinvoke</classname>&lt;S&lt;X<subscript>0</subscript>,...X<subscript>n</subscript>&gt; &gt;</computeroutput>,
                     then the result type is calculated as follows:
@@ -262,6 +252,16 @@
                     </itemizedlist>
                   </listitem>
                   <listitem>
+ <para>
+ If <computeroutput><classname>proto::is_transform</classname>&lt;O&gt;::value</computeroutput> is
+ <computeroutput>true</computeroutput>, then let the result type be
+ <computeroutput>
+ boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>_</classname>, O&gt;(Expr, State, Data)&gt;::type
+ </computeroutput>.
+ Note that a substitution took place.
+ </para>
+ </listitem>
+ <listitem>
                     Otherwise, the result type is <computeroutput>O</computeroutput>, and note that no
                     substitution took place.
                   </listitem>


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