Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49937 - in branches/release: . boost/proto boost/proto/detail libs/proto/doc libs/proto/doc/reference libs/proto/example libs/proto/test
From: eric_at_[hidden]
Date: 2008-11-26 00:59:04


Author: eric_niebler
Date: 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
New Revision: 49937
URL: http://svn.boost.org/trac/boost/changeset/49937

Log:
Merged revisions 49910,49930,49935-49936 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49910 | eric_niebler | 2008-11-23 23:17:40 -0800 (Sun, 23 Nov 2008) | 1 line
  
  add an example of virtual data members
........
  r49930 | eric_niebler | 2008-11-25 08:00:40 -0800 (Tue, 25 Nov 2008) | 1 line
  
  deprecate old BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE macro, replace with more flexible and useful BOOST_PROTO_REPEAT and BOOST_PROTO_LOCAL_ITERATE
........
  r49935 | eric_niebler | 2008-11-25 16:44:00 -0800 (Tue, 25 Nov 2008) | 1 line
  
  reference documentation for new repetition and iteration macros
........
  r49936 | eric_niebler | 2008-11-25 18:10:38 -0800 (Tue, 25 Nov 2008) | 1 line
  
  user documentation for the new repetition and iteration macros
........

Added:
   branches/release/boost/proto/detail/deprecated.hpp
      - copied unchanged from r49930, /trunk/boost/proto/detail/deprecated.hpp
   branches/release/boost/proto/detail/local.hpp
      - copied unchanged from r49930, /trunk/boost/proto/detail/local.hpp
   branches/release/boost/proto/repeat.hpp
      - copied, changed from r49930, /trunk/boost/proto/repeat.hpp
   branches/release/libs/proto/doc/reference/repeat.xml
      - copied unchanged from r49936, /trunk/libs/proto/doc/reference/repeat.xml
   branches/release/libs/proto/example/virtual_member.cpp
      - copied, changed from r49910, /trunk/libs/proto/example/virtual_member.cpp
Properties modified:
   branches/release/ (props changed)
Text files modified:
   branches/release/boost/proto/core.hpp | 1
   branches/release/boost/proto/make_expr.hpp | 225 ---------------------------------------
   branches/release/boost/proto/repeat.hpp | 216 ++++++++++++++++++++++++++++++++++++++
   branches/release/libs/proto/doc/front_end.qbk | 78 +++++++++++++
   branches/release/libs/proto/doc/proto.qbk | 28 ++++
   branches/release/libs/proto/doc/reference.xml | 1
   branches/release/libs/proto/example/Jamfile.v2 | 4
   branches/release/libs/proto/example/mini_lambda.cpp | 95 +++++++++++-----
   branches/release/libs/proto/example/virtual_member.cpp | 70 ++++-------
   branches/release/libs/proto/test/lambda.cpp | 30 ++---
   10 files changed, 432 insertions(+), 316 deletions(-)

Modified: branches/release/boost/proto/core.hpp
==============================================================================
--- branches/release/boost/proto/core.hpp (original)
+++ branches/release/boost/proto/core.hpp 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -16,6 +16,7 @@
 #include <boost/proto/tags.hpp>
 #include <boost/proto/eval.hpp>
 #include <boost/proto/expr.hpp>
+#include <boost/proto/repeat.hpp>
 #include <boost/proto/traits.hpp>
 #include <boost/proto/domain.hpp>
 #include <boost/proto/fusion.hpp>

Modified: branches/release/boost/proto/make_expr.hpp
==============================================================================
--- branches/release/boost/proto/make_expr.hpp (original)
+++ branches/release/boost/proto/make_expr.hpp 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -17,37 +17,20 @@
     #include <boost/config.hpp>
     #include <boost/detail/workaround.hpp>
     #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/control/if.hpp>
- #include <boost/preprocessor/control/expr_if.hpp>
     #include <boost/preprocessor/arithmetic/inc.hpp>
     #include <boost/preprocessor/arithmetic/dec.hpp>
     #include <boost/preprocessor/arithmetic/sub.hpp>
     #include <boost/preprocessor/punctuation/comma_if.hpp>
     #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/facilities/intercept.hpp>
- #include <boost/preprocessor/comparison/greater.hpp>
- #include <boost/preprocessor/tuple/elem.hpp>
- #include <boost/preprocessor/tuple/to_list.hpp>
- #include <boost/preprocessor/logical/and.hpp>
     #include <boost/preprocessor/repetition/enum.hpp>
     #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing.hpp>
     #include <boost/preprocessor/repetition/enum_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
     #include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
- #include <boost/preprocessor/repetition/repeat_from_to.hpp>
- #include <boost/preprocessor/seq/size.hpp>
- #include <boost/preprocessor/seq/enum.hpp>
- #include <boost/preprocessor/seq/seq.hpp>
- #include <boost/preprocessor/seq/to_tuple.hpp>
- #include <boost/preprocessor/seq/for_each_i.hpp>
- #include <boost/preprocessor/seq/pop_back.hpp>
- #include <boost/preprocessor/seq/push_back.hpp>
- #include <boost/preprocessor/seq/push_front.hpp>
- #include <boost/preprocessor/list/for_each_i.hpp>
     #include <boost/ref.hpp>
     #include <boost/mpl/if.hpp>
     #include <boost/mpl/assert.hpp>
@@ -73,6 +56,7 @@
     # include <boost/spirit/fusion/sequence/size.hpp>
     #endif
     #include <boost/proto/detail/poly_function.hpp>
+ #include <boost/proto/detail/deprecated.hpp>
     #include <boost/proto/detail/suffix.hpp>
 
     #ifdef _MSC_VER
@@ -148,213 +132,6 @@
>::call(BOOST_PROTO_AT(Z, N, DATA)) \
         /**/
 
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_TEMPLATE_AUX_(R, DATA, I, ELEM) \
- (ELEM BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_TEMPLATE_YES_(R, DATA, I, ELEM) \
- BOOST_PP_LIST_FOR_EACH_I_R( \
- R \
- , BOOST_PROTO_VARARG_TEMPLATE_AUX_ \
- , I \
- , BOOST_PP_TUPLE_TO_LIST( \
- BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
- , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \
- ) \
- ) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_TEMPLATE_NO_(R, DATA, I, ELEM) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_TEMPLATE_(R, DATA, I, ELEM) \
- BOOST_PP_IF( \
- BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
- , BOOST_PROTO_VARARG_TEMPLATE_YES_ \
- , BOOST_PROTO_VARARG_TEMPLATE_NO_ \
- )(R, DATA, I, ELEM) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_TYPE_AUX_(R, DATA, I, ELEM) \
- (BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_TEMPLATE_PARAMS_YES_(R, DATA, I, ELEM) \
- < \
- BOOST_PP_SEQ_ENUM( \
- BOOST_PP_LIST_FOR_EACH_I_R( \
- R \
- , BOOST_PROTO_VARARG_TYPE_AUX_ \
- , I \
- , BOOST_PP_TUPLE_TO_LIST( \
- BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
- , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \
- ) \
- ) \
- ) \
- > \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_TEMPLATE_PARAMS_NO_(R, DATA, I, ELEM) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_TYPE_(R, DATA, I, ELEM) \
- BOOST_PP_COMMA_IF(I) \
- BOOST_PP_SEQ_HEAD(ELEM) \
- BOOST_PP_IF( \
- BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
- , BOOST_PROTO_TEMPLATE_PARAMS_YES_ \
- , BOOST_PROTO_TEMPLATE_PARAMS_NO_ \
- )(R, DATA, I, ELEM) BOOST_PP_EXPR_IF(BOOST_PP_GREATER(I, 1), const) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM) \
- BOOST_PP_EXPR_IF( \
- BOOST_PP_GREATER(I, 1) \
- , (( \
- BOOST_PP_SEQ_HEAD(ELEM) \
- BOOST_PP_IF( \
- BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
- , BOOST_PROTO_TEMPLATE_PARAMS_YES_ \
- , BOOST_PROTO_TEMPLATE_PARAMS_NO_ \
- )(R, DATA, I, ELEM)() \
- )) \
- ) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_AS_CHILD_(Z, N, DATA) \
- (BOOST_PP_CAT(DATA, N)) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_SEQ_PUSH_FRONT(SEQ, ELEM) \
- BOOST_PP_SEQ_POP_BACK(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_BACK(SEQ, _dummy_), ELEM)) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_AS_PARAM_(Z, N, DATA) \
- (BOOST_PP_CAT(DATA, N)) \
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VARARG_FUN_(Z, N, DATA) \
- template< \
- BOOST_PP_SEQ_ENUM( \
- BOOST_PP_SEQ_FOR_EACH_I( \
- BOOST_PROTO_VARARG_TEMPLATE_, ~ \
- , BOOST_PP_SEQ_PUSH_FRONT( \
- BOOST_PROTO_SEQ_PUSH_FRONT( \
- BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
- , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
- ) \
- , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
- ) \
- ) \
- BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_PARAM_, typename A) \
- ) \
- > \
- typename boost::proto::result_of::make_expr< \
- BOOST_PP_SEQ_FOR_EACH_I( \
- BOOST_PROTO_VARARG_TYPE_, ~ \
- , BOOST_PP_SEQ_PUSH_FRONT( \
- BOOST_PROTO_SEQ_PUSH_FRONT( \
- BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
- , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
- ) \
- , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
- ) \
- ) \
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
- >::type const \
- BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) \
- { \
- return boost::proto::detail::make_expr_< \
- BOOST_PP_SEQ_FOR_EACH_I( \
- BOOST_PROTO_VARARG_TYPE_, ~ \
- , BOOST_PP_SEQ_PUSH_FRONT( \
- BOOST_PROTO_SEQ_PUSH_FRONT( \
- BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
- , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
- ) \
- , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
- ) \
- ) \
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
- >()( \
- BOOST_PP_SEQ_ENUM( \
- BOOST_PP_SEQ_FOR_EACH_I( \
- BOOST_PROTO_VARARG_AS_EXPR_, ~ \
- , BOOST_PP_SEQ_PUSH_FRONT( \
- BOOST_PROTO_SEQ_PUSH_FRONT( \
- BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
- , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
- ) \
- , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
- ) \
- ) \
- BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_CHILD_, a) \
- ) \
- ); \
- } \
- /**/
-
- /// \code
- /// BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
- /// 1
- /// , construct
- /// , boost::proto::default_domain
- /// , (boost::proto::tag::function)
- /// , ((op::construct)(typename)(int))
- /// )
- /// \endcode
- #define BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(ARGCOUNT, NAME, DOMAIN, TAG, BOUNDARGS) \
- BOOST_PP_REPEAT_FROM_TO( \
- ARGCOUNT \
- , BOOST_PP_INC(ARGCOUNT) \
- , BOOST_PROTO_VARARG_FUN_ \
- , (NAME, TAG, BOUNDARGS, DOMAIN) \
- )\
- /**/
-
- /// \code
- /// BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
- /// construct
- /// , boost::proto::default_domain
- /// , (boost::proto::tag::function)
- /// , ((op::construct)(typename)(int))
- /// )
- /// \endcode
- #define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(NAME, DOMAIN, TAG, BOUNDARGS) \
- BOOST_PP_REPEAT( \
- BOOST_PP_SUB(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PP_SEQ_SIZE(BOUNDARGS)) \
- , BOOST_PROTO_VARARG_FUN_ \
- , (NAME, TAG, BOUNDARGS, DOMAIN) \
- ) \
- /**/
-
         namespace detail
         {
             template<typename T, typename Domain>

Copied: branches/release/boost/proto/repeat.hpp (from r49930, /trunk/boost/proto/repeat.hpp)
==============================================================================
--- /trunk/boost/proto/repeat.hpp (original)
+++ branches/release/boost/proto/repeat.hpp 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -75,18 +75,234 @@
 #define BOOST_PROTO_invoke(Z, N, DATA)\
   BOOST_PP_TUPLE_ELEM(5,0,DATA)(N, BOOST_PP_TUPLE_ELEM(5,1,DATA), BOOST_PP_TUPLE_ELEM(5,2,DATA), BOOST_PP_TUPLE_ELEM(5,3,DATA), BOOST_PP_TUPLE_ELEM(5,4,DATA))
 
+/// \brief Repeatedly invoke the specified macro.
+///
+/// BOOST_PROTO_REPEAT_FROM_TO_EX() is used generate the kind of repetitive code that is typical
+/// of DSELs built with Proto. BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a) is equivalent to:
+///
+/// \code
+/// MACRO(FROM, typename_A, A, A_a, a)
+/// MACRO(FROM+1, typename_A, A, A_a, a)
+/// ...
+/// MACRO(TO-1, typename_A, A, A_a, a)
+/// \endcode
 #define BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a)\
   BOOST_PP_REPEAT_FROM_TO(FROM, TO, BOOST_PROTO_invoke, (MACRO, typename_A, A, A_a, a))
 
+/// \brief Repeatedly invoke the specified macro.
+///
+/// BOOST_PROTO_REPEAT_FROM_TO() is used generate the kind of repetitive code that is typical
+/// of DSELs built with Proto. BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO) is equivalent to:
+///
+/// \code
+/// MACRO(FROM, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+/// MACRO(FROM+1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+/// ...
+/// MACRO(TO-1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+/// \endcode
+///
+/// Example:
+///
+/// \code
+/// // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
+/// // following construct() function template.
+/// #define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
+/// template<typename T, typename_A(N)> \
+/// typename proto::result_of::make_expr< \
+/// proto::tag::function \
+/// , construct_helper<T> \
+/// , A_const_ref(N) \
+/// >::type const \
+/// construct(A_const_ref_a(N)) \
+/// { \
+/// return proto::make_expr< \
+/// proto::tag::function \
+/// >( \
+/// construct_helper<T>() \
+/// , ref_a(N) \
+/// ); \
+/// }
+/// BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0)
+/// #undef M0
+/// \endcode
+///
+/// The above invocation of BOOST_PROTO_REPEAT_FROM_TO() will generate
+/// the following code:
+///
+/// \code
+/// template<typename T, typename A0>
+/// typename proto::result_of::make_expr<
+/// proto::tag::function
+/// , construct_helper<T>
+/// , A0 const &
+/// >::type const
+/// construct(A0 const & a0)
+/// {
+/// return proto::make_expr<
+/// proto::tag::function
+/// >(
+/// construct_helper<T>()
+/// , boost::ref(a0)
+/// );
+/// }
+///
+/// template<typename T, typename A0, typename A1>
+/// typename proto::result_of::make_expr<
+/// proto::tag::function
+/// , construct_helper<T>
+/// , A0 const &
+/// , A1 const &
+/// >::type const
+/// construct(A0 const & a0, A1 const & a1)
+/// {
+/// return proto::make_expr<
+/// proto::tag::function
+/// >(
+/// construct_helper<T>()
+/// , boost::ref(a0)
+/// , boost::ref(a1)
+/// );
+/// }
+///
+/// // ... and so on, up to BOOST_PROTO_MAX_ARITY-1 arguments ...
+/// \endcode
 #define BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO)\
   BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
 
+/// \brief Repeatedly invoke the specified macro.
+///
+/// BOOST_PROTO_REPEAT_EX() is used generate the kind of repetitive code that is typical
+/// of DSELs built with Proto. BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a) is equivalent to:
+///
+/// \code
+/// MACRO(1, typename_A, A, A_a, a)
+/// MACRO(2, typename_A, A, A_a, a)
+/// ...
+/// MACRO(BOOST_PROTO_MAX_ARITY, typename_A, A, A_a, a)
+/// \endcode
 #define BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a)\
   BOOST_PROTO_REPEAT_FROM_TO_EX(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
 
+/// \brief Repeatedly invoke the specified macro.
+///
+/// BOOST_PROTO_REPEAT() is used generate the kind of repetitive code that is typical
+/// of DSELs built with Proto. BOOST_PROTO_REPEAT(MACRO) is equivalent to:
+///
+/// \code
+/// MACRO(1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+/// MACRO(2, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+/// ...
+/// MACRO(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
+/// \endcode
 #define BOOST_PROTO_REPEAT(MACRO)\
   BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO)
 
+/// \brief Repeatedly invoke the specified macro.
+///
+/// BOOST_PROTO_LOCAL_ITERATE() is used generate the kind of repetitive code that is typical
+/// of DSELs built with Proto. This macro causes the user-defined macro BOOST_PROTO_LOCAL_MACRO to
+/// be expanded with values in the range specified by BOOST_PROTO_LOCAL_LIMITS.
+///
+/// Usage:
+///
+/// \code
+/// #include BOOST_PROTO_LOCAL_ITERATE()
+/// \endcode
+///
+/// Example:
+///
+/// \code
+/// // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
+/// // following construct() function template.
+/// #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, \
+/// A_const_ref_a, ref_a) \
+/// template<typename T, typename_A(N)> \
+/// typename proto::result_of::make_expr< \
+/// proto::tag::function \
+/// , construct_helper<T> \
+/// , A_const_ref(N) \
+/// >::type const \
+/// construct(A_const_ref_a(N)) \
+/// { \
+/// return proto::make_expr< \
+/// proto::tag::function \
+/// >( \
+/// construct_helper<T>() \
+/// , ref_a(N) \
+/// ); \
+/// }
+/// #define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY))
+/// #include BOOST_PROTO_LOCAL_ITERATE()
+/// \endcode
+///
+/// The above inclusion of BOOST_PROTO_LOCAL_ITERATE() will generate
+/// the following code:
+///
+/// \code
+/// template<typename T, typename A0>
+/// typename proto::result_of::make_expr<
+/// proto::tag::function
+/// , construct_helper<T>
+/// , A0 const &
+/// >::type const
+/// construct(A0 const & a0)
+/// {
+/// return proto::make_expr<
+/// proto::tag::function
+/// >(
+/// construct_helper<T>()
+/// , boost::ref(a0)
+/// );
+/// }
+///
+/// template<typename T, typename A0, typename A1>
+/// typename proto::result_of::make_expr<
+/// proto::tag::function
+/// , construct_helper<T>
+/// , A0 const &
+/// , A1 const &
+/// >::type const
+/// construct(A0 const & a0, A1 const & a1)
+/// {
+/// return proto::make_expr<
+/// proto::tag::function
+/// >(
+/// construct_helper<T>()
+/// , boost::ref(a0)
+/// , boost::ref(a1)
+/// );
+/// }
+///
+/// // ... and so on, up to BOOST_PROTO_MAX_ARITY-1 arguments ...
+/// \endcode
+///
+/// If BOOST_PROTO_LOCAL_LIMITS is not defined by the user, it defaults
+/// to (1, BOOST_PROTO_MAX_ARITY)
+///
+/// At each iteration, BOOST_PROTO_LOCAL_MACRO is invoked with the current
+/// iteration number and the following 4 macro parameters:
+///
+/// \li BOOST_PROTO_LOCAL_typename_A
+/// \li BOOST_PROTO_LOCAL_A
+/// \li BOOST_PROTO_LOCAL_A_a
+/// \li BOOST_PROTO_LOCAL_a
+///
+/// If these macros are not defined by the user, they default respectively to:
+///
+/// \li BOOST_PROTO_typename_A
+/// \li BOOST_PROTO_A_const_ref
+/// \li BOOST_PROTO_A_const_ref_a
+/// \li BOOST_PROTO_ref_a
+///
+/// After including BOOST_PROTO_LOCAL_ITERATE(), the following macros are
+/// automatically undefined:
+///
+/// \li BOOST_PROTO_LOCAL_MACRO
+/// \li BOOST_PROTO_LOCAL_LIMITS
+/// \li BOOST_PROTO_LOCAL_typename_A
+/// \li BOOST_PROTO_LOCAL_A
+/// \li BOOST_PROTO_LOCAL_A_a
+/// \li BOOST_PROTO_LOCAL_a
 #define BOOST_PROTO_LOCAL_ITERATE() <boost/proto/detail/local.hpp>
 
 #endif

Modified: branches/release/libs/proto/doc/front_end.qbk
==============================================================================
--- branches/release/libs/proto/doc/front_end.qbk (original)
+++ branches/release/libs/proto/doc/front_end.qbk 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -650,4 +650,82 @@
 
 [endsect]
 
+[/=======================================================================]
+[section:code_repetition Generating Repetitive Code with the Preprocessor]
+[/=======================================================================]
+
+Sometimes as a DSEL designer, to make the lives of your users easy, you have to make your own life hard. Giving your users natural and flexible syntax often involves writing large numbers of repetitive function overloads. It can be enough to give you repetitive stress injury! Before you hurt yourself, check out the macros Proto provides for automating many repetitive code-generation chores.
+
+Imagine that we are writing a lambda DSEL, and we would like to enable syntax for constructing temporary objects of any type using the following syntax:
+
+ // A lambda expression that takes two arguments and
+ // uses them to construct a temporary std::complex<>
+ construct< std::complex<int> >( _1, _2 )
+
+For the sake of the discussion, imagine that we already have a function object template `construct_impl<>` that accepts arguments and constructs new objects from them. We would want the above lambda expression to be equivalent to the following:
+
+ // The above lambda expression should be roughly equivalent
+ // to the following:
+ proto::make_expr<proto::tag::function>(
+ construct_impl<std::complex<int> >() // The function to invoke lazily
+ , boost::ref(_1) // The first argument to the function
+ , boost::ref(_2) // The second argument to the function
+ );
+
+We can define our `construct()` function template as follows:
+
+ template<typename T, typename A0, typename A1>
+ typename proto::result_of::make_expr<
+ proto::tag::function
+ , construct_impl<T>
+ , A0 const &
+ , A1 const &
+ >::type const
+ construct(A0 const &a0, A1 const &a1)
+ {
+ return proto::make_expr<proto::tag::function>(
+ construct_impl<T>()
+ , boost::ref(a0)
+ , boost::ref(a1)
+ );
+ }
+
+This works for two arguments, but we would like it to work for any number of arguments, up to (_MAX_ARITY_ - 1). (Why "- 1"? Because one child is taken up by the `construct_impl<T>()` terminal leaving room for only (_MAX_ARITY_ - 1) other children.)
+
+For cases like this, Proto provides the _REPEAT_ and _REPEAT_FROM_TO_ macros. To use it, we turn the function definition above into a macro as follows:
+
+ #define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
+ template<typename T, typename_A(N)> \
+ typename proto::result_of::make_expr< \
+ proto::tag::function \
+ , construct_impl<T> \
+ , A_const_ref(N) \
+ >::type const \
+ construct(A_const_ref_a(N)) \
+ { \
+ return proto::make_expr<proto::tag::function>( \
+ construct_impl<T>() \
+ , ref_a(N) \
+ ); \
+ }
+
+Notice that we turned the function into a macro that takes 5 arguments. The first is the current iteration number. The rest are the names of other macros that generate different sequences. For instance, Proto passes as the second parameter the name of a macro that will expand to `typename A0, typename A1, ...`.
+
+Now that we have turned our function into a macro, we can pass the macro to _REPEAT_FROM_TO_. Proto will invoke it iteratively, generating all the function overloads for us.
+
+ // Generate overloads of construct() that accept from
+ // 1 to BOOST_PROTO_MAX_ARITY-1 arguments:
+ BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0)
+ #undef M0
+
+[/============================]
+[heading Non-Default Sequences]
+[/============================]
+
+As mentioned above, Proto passes as the last 4 arguments to your macro the names of other macros that generate various sequences. The macros _REPEAT_ and _REPEAT_FROM_TO_ select defaults for these parameters. If the defaults do not meet your needs, you can use _REPEAT_EX_ and _REPEAT_FROM_TO_EX_ and pass different macros that generate different sequences. Proto defines a number of such macros for use as parameters to _REPEAT_EX_ and _REPEAT_FROM_TO_EX_. Check the reference section for [headerref boost/proto/repeat.hpp] for all the details.
+
+Also, check out _LOCAL_ITERATE_. It works similarly to _REPEAT_ and friends, but it can be easier to use when you want to change one macro argument and accept defaults for the others.
+
+[endsect]
+
 [endsect]

Modified: branches/release/libs/proto/doc/proto.qbk
==============================================================================
--- branches/release/libs/proto/doc/proto.qbk (original)
+++ branches/release/libs/proto/doc/proto.qbk 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -197,6 +197,34 @@
   [^[macroref BOOST_PROTO_DEFINE_OPERATORS]()]]
 [def _AUTO_
   [^[macroref BOOST_PROTO_AUTO]()]]
+[def _REPEAT_
+ [^[macroref BOOST_PROTO_REPEAT]()]]
+[def _REPEAT_FROM_TO_
+ [^[macroref BOOST_PROTO_REPEAT_FROM_TO]()]]
+[def _REPEAT_EX_
+ [^[macroref BOOST_PROTO_REPEAT_EX]()]]
+[def _REPEAT_FROM_TO_EX_
+ [^[macroref BOOST_PROTO_REPEAT_FROM_TO_EX]()]]
+[def _LOCAL_ITERATE_
+ [^[macroref BOOST_PROTO_LOCAL_ITERATE]()]]
+[def _BOOST_PROTO_typename_A_
+ [^[macroref BOOST_PROTO_typename_A]()]]
+[def _BOOST_PROTO_A_
+ [^[macroref BOOST_PROTO_A]()]]
+[def _BOOST_PROTO_A_const_
+ [^[macroref BOOST_PROTO_A_const]()]]
+[def _BOOST_PROTO_A_ref_
+ [^[macroref BOOST_PROTO_A_ref]()]]
+[def _BOOST_PROTO_A_const_ref_
+ [^[macroref BOOST_PROTO_A_const_ref]()]]
+[def _BOOST_PROTO_A_ref_a_
+ [^[macroref BOOST_PROTO_A_ref_a]()]]
+[def _BOOST_PROTO_A_const_ref_a_
+ [^[macroref BOOST_PROTO_A_const_ref_a]()]]
+[def _BOOST_PROTO_a_
+ [^[macroref BOOST_PROTO_a]()]]
+[def _BOOST_PROTO_ref_a_
+ [^[macroref BOOST_PROTO_ref_a]()]]
 
 [include preface.qbk]
 

Modified: branches/release/libs/proto/doc/reference.xml
==============================================================================
--- branches/release/libs/proto/doc/reference.xml (original)
+++ branches/release/libs/proto/doc/reference.xml 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -1012,6 +1012,7 @@
   <xi:include href="reference/proto.xml"/>
   <xi:include href="reference/proto_fwd.xml"/>
   <xi:include href="reference/proto_typeof.xml"/>
+ <xi:include href="reference/repeat.xml"/>
   <xi:include href="reference/tags.xml"/>
   <xi:include href="reference/traits.xml"/>
   <xi:include href="reference/transform/arg.xml"/>

Modified: branches/release/libs/proto/example/Jamfile.v2
==============================================================================
--- branches/release/libs/proto/example/Jamfile.v2 (original)
+++ branches/release/libs/proto/example/Jamfile.v2 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -68,3 +68,7 @@
         mini_lambda.cpp
     ;
 
+exe virtual_member
+ :
+ virtual_member.cpp
+ ;

Modified: branches/release/libs/proto/example/mini_lambda.cpp
==============================================================================
--- branches/release/libs/proto/example/mini_lambda.cpp (original)
+++ branches/release/libs/proto/example/mini_lambda.cpp 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -46,7 +46,7 @@
 };
 
 // The lambda grammar, with the transforms for calculating the max arity
-struct Lambda
+struct lambda_arity
   : proto::or_<
         proto::when<
             proto::terminal< placeholder<_> >
@@ -57,17 +57,11 @@
>
       , proto::when<
             proto::nary_expr<_, proto::vararg<_> >
- , proto::fold<_, mpl::int_<0>(), mpl::max<Lambda,proto::_state>()>
+ , proto::fold<_, mpl::int_<0>(), mpl::max<lambda_arity, proto::_state>()>
>
>
 {};
 
-// simple wrapper for calculating a lambda expression's arity.
-template<typename Expr>
-struct lambda_arity
- : boost::result_of<Lambda(Expr, mpl::void_, mpl::void_)>
-{};
-
 // The lambda context is the same as the default context
 // with the addition of special handling for lambda placeholders
 template<typename Tuple>
@@ -105,16 +99,38 @@
     BOOST_PROTO_EXTENDS_ASSIGN()
     BOOST_PROTO_EXTENDS_SUBSCRIPT()
 
- // Careful not to evaluate the return type of the nullary function
- // unless we have a nullary lambda!
- typedef typename mpl::eval_if<
- typename lambda_arity<T>::type
- , mpl::identity<void>
- , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
- >::type nullary_type;
+ // Calculate the arity of this lambda expression
+ static int const arity = boost::result_of<lambda_arity(T)>::type::value;
+
+ template<typename Sig>
+ struct result;
+
+ // Define nested result<> specializations to calculate the return
+ // type of this lambda expression. But be careful not to evaluate
+ // the return type of the nullary function unless we have a nullary
+ // lambda!
+ template<typename This>
+ struct result<This()>
+ : mpl::eval_if_c<
+ 0 == arity
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ , mpl::identity<void>
+ >
+ {};
+
+ template<typename This, typename A0>
+ struct result<This(A0)>
+ : proto::result_of::eval<T const, lambda_context<fusion::tuple<A0> > >
+ {};
+
+ template<typename This, typename A0, typename A1>
+ struct result<This(A0, A1)>
+ : proto::result_of::eval<T const, lambda_context<fusion::tuple<A0, A1> > >
+ {};
 
     // Define our operator () that evaluates the lambda expression.
- nullary_type operator ()() const
+ typename result<lambda()>::type
+ operator ()() const
     {
         fusion::tuple<> args;
         lambda_context<fusion::tuple<> > ctx(args);
@@ -122,7 +138,7 @@
     }
 
     template<typename A0>
- typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ typename result<lambda(A0 const &)>::type
     operator ()(A0 const &a0) const
     {
         fusion::tuple<A0 const &> args(a0);
@@ -131,7 +147,7 @@
     }
 
     template<typename A0, typename A1>
- typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ typename result<lambda(A0 const &, A1 const &)>::type
     operator ()(A0 const &a0, A1 const &a1) const
     {
         fusion::tuple<A0 const &, A1 const &> args(a0, a1);
@@ -166,23 +182,38 @@
     T operator()() const
     { return T(); }
 
- template<typename A0>
- T operator()(A0 const &a0) const
- { return T(a0); }
-
- template<typename A0, typename A1>
- T operator()(A0 const &a0, A1 const &a1) const
- { return T(a0, a1); }
+ // Generate BOOST_PROTO_MAX_ARITY overloads of the
+ // followig function call operator.
+#define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a)\
+ template<typename_A(N)> \
+ T operator()(A_const_ref_a(N)) const \
+ { return T(a(N)); }
+#define BOOST_PROTO_LOCAL_a BOOST_PROTO_a
+#include BOOST_PROTO_LOCAL_ITERATE()
 };
 
 // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
-// construct function template like the one defined above.
-BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
- construct \
- , lambda_domain \
- , (proto::tag::function) \
- , ((construct_helper)(typename)) \
-)
+// following construct() function template.
+#define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
+template<typename T, typename_A(N)> \
+typename proto::result_of::make_expr< \
+ proto::tag::function \
+ , lambda_domain \
+ , construct_helper<T> \
+ , A_const_ref(N) \
+>::type const \
+construct(A_const_ref_a(N)) \
+{ \
+ return proto::make_expr< \
+ proto::tag::function \
+ , lambda_domain \
+ >( \
+ construct_helper<T>() \
+ , ref_a(N) \
+ ); \
+}
+BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0)
+#undef M0
 
 struct S
 {

Copied: branches/release/libs/proto/example/virtual_member.cpp (from r49910, /trunk/libs/proto/example/virtual_member.cpp)
==============================================================================
--- /trunk/libs/proto/example/virtual_member.cpp (original)
+++ branches/release/libs/proto/example/virtual_member.cpp 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -202,9 +202,8 @@
             ((keyword::catch_, catch_))
         )
 
- BOOST_STATIC_CONSTANT(
- int, arity = boost::result_of<arity_of(E)>::type::value
- );
+ // Calculate the arity of this lambda expression
+ static int const arity = boost::result_of<arity_of(E)>::type::value;
 
         // Define overloads of operator() that evaluate the lambda
         // expression for up to 3 arguments.
@@ -214,53 +213,38 @@
         typename mpl::eval_if_c<
             0 != arity
           , mpl::identity<void>
- , boost::result_of<grammar(E const &, int const &, fusion::vector0 &)>
+ , boost::result_of<grammar(
+ E const &
+ , int const &
+ , fusion::vector<> &
+ )>
>::type
         operator()() const
         {
             BOOST_MPL_ASSERT_RELATION(arity, ==, 0);
- fusion::vector0 args;
+ fusion::vector<> args;
             return grammar()(proto_base(), 0, args);
         }
 
- template<typename A0>
- typename boost::result_of<grammar(
- E const &
- , int const &
- , fusion::vector1<A0 const &> &
- )>::type
- operator ()(A0 const &a0) const
- {
- BOOST_MPL_ASSERT_RELATION(arity, <=, 1);
- fusion::vector1<A0 const &> args(a0);
- return grammar()(proto_base(), 0, args);
- }
-
- template<typename A0, typename A1>
- typename boost::result_of<grammar(
- E const &
- , int const &
- , fusion::vector2<A0 const &, A1 const &> &
- )>::type
- operator ()(A0 const &a0, A1 const &a1) const
- {
- BOOST_MPL_ASSERT_RELATION(arity, <=, 2);
- fusion::vector2<A0 const &, A1 const &> args(a0, a1);
- return grammar()(proto_base(), 0, args);
- }
-
- template<typename A0, typename A1, typename A2>
- typename boost::result_of<grammar(
- E const &
- , int const &
- , fusion::vector3<A0 const &, A1 const &, A2 const &> &
- )>::type
- operator ()(A0 const &a0, A1 const &a1, A2 const &a2) const
- {
- BOOST_MPL_ASSERT_RELATION(arity, <=, 3);
- fusion::vector3<A0 const &, A1 const &, A2 const &> args(a0, a1, a2);
- return grammar()(proto_base(), 0, args);
- }
+ #define LAMBDA_EVAL(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
+ template<typename_A(N)> \
+ typename boost::result_of<grammar( \
+ E const & \
+ , int const & \
+ , fusion::vector<A_const_ref(N)> & \
+ )>::type \
+ operator ()(A_const_ref_a(N)) const \
+ { \
+ BOOST_MPL_ASSERT_RELATION(arity, <=, N); \
+ fusion::vector<A_const_ref(N)> args(ref_a(N)); \
+ return grammar()(proto_base(), 0, args); \
+ } \
+ /**/
+
+ // Repeats LAMBDA_EVAL macro for N=1 to 3 inclusive (because
+ // there are only 3 placeholders)
+ BOOST_PROTO_REPEAT_FROM_TO(1, 4, LAMBDA_EVAL)
+ #undef LAMBDA_EVAL
     };
 
     namespace placeholders

Modified: branches/release/libs/proto/test/lambda.cpp
==============================================================================
--- branches/release/libs/proto/test/lambda.cpp (original)
+++ branches/release/libs/proto/test/lambda.cpp 2008-11-26 00:59:02 EST (Wed, 26 Nov 2008)
@@ -130,28 +130,24 @@
         return proto::eval(*this, ctx);
     }
 
- template<typename A0>
- typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
- operator ()(A0 const &a0) const
- {
- fusion::tuple<A0 const &> args(a0);
- lambda_context<fusion::tuple<A0 const &> > ctx(args);
- return proto::eval(*this, ctx);
- }
-
- template<typename A0, typename A1>
- typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
- operator ()(A0 const &a0, A1 const &a1) const
- {
- fusion::tuple<A0 const &, A1 const &> args(a0, a1);
- lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
- return proto::eval(*this, ctx);
- }
+ #define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \
+ template<typename_A(N)> \
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A_const_ref(N)> > >::type \
+ operator ()(A_const_ref_a(N)) const \
+ { \
+ fusion::tuple<A_const_ref(N)> args(ref_a(N)); \
+ lambda_context<fusion::tuple<A_const_ref(N)> > ctx(args); \
+ return proto::eval(*this, ctx); \
+ } \
+ /**/
+ BOOST_PROTO_REPEAT_FROM_TO(1, 4, M0)
+ #undef M0
 };
 
 // Define some lambda placeholders
 lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
 lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<3> > >::type> const _3 = {{}};
 
 template<typename T>
 lambda<typename proto::terminal<T>::type> const val(T const &t)


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