|
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_<<replaceable>true-or-false</replaceable>></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<></computeroutput> is used by the
+ <computeroutput><classname alt="proto::make">proto::make<></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<></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<T>::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<></classname></computeroutput>,
+ <computeroutput>proto::is_transform<T>::value</computeroutput> is <computeroutput>true</computeroutput>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, <computeroutput>proto::is_transform<T>::value</computeroutput>
+ is <computeroutput>false</computeroutput>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </description>
+ <inherit><type>mpl::bool_<<replaceable>true-or-false</replaceable>></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><T>::value</computeroutput> is
+ <computeroutput>true</computeroutput>.
+ </para>
+ <para>
<computeroutput><classname>proto::call</classname><T>::impl<Expr,State,Data>::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><T>::impl<Expr,State,Data>::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><T>::value</computeroutput> is
+ <computeroutput>true</computeroutput>.
+ </para>
+ <para>
+ <computeroutput><classname>proto::call</classname><T>::impl<Expr,State,Data>::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><<classname>_</classname>,A<subscript>0</subscript>>()(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><<classname>_</classname>,A<subscript>0</subscript>>()(expr, state, data),
<classname>when</classname><<classname>_</classname>,A<subscript>1</subscript>>()(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><<classname>_</classname>,A<subscript>0</subscript>>()(expr, state, data),
<classname>when</classname><<classname>_</classname>,A<subscript>1</subscript>>()(expr, state, data),
<classname>when</classname><<classname>_</classname>,A<subscript>2</subscript>>()(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><<classname>_</classname>,A<subscript>0</subscript>>()(expr, state, data),
...
<classname>when</classname><<classname>_</classname>,A<subscript>n</subscript>>()(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<<classname>proto::when</classname><<classname>_</classname>, O>(Expr, State, Data)>::type
- </computeroutput>.
- Note that a substitution took place.
- </para>
- </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>,
then the result type is calculated as follows:
@@ -262,6 +252,16 @@
</itemizedlist>
</listitem>
<listitem>
+ <para>
+ If <computeroutput><classname>proto::is_transform</classname><O>::value</computeroutput> is
+ <computeroutput>true</computeroutput>, then let the result type be
+ <computeroutput>
+ boost::result_of<<classname>proto::when</classname><<classname>_</classname>, O>(Expr, State, Data)>::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