Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:34

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file repeat.hpp
0003 /// Contains macros to ease the generation of repetitious code constructs
0004 //
0005 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0006 //  Software License, Version 1.0. (See accompanying file
0007 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #ifndef BOOST_PROTO_REPEAT_HPP_EAN_11_24_2008
0010 #define BOOST_PROTO_REPEAT_HPP_EAN_11_24_2008
0011 
0012 #include <boost/preprocessor/cat.hpp>
0013 #include <boost/preprocessor/facilities/intercept.hpp>
0014 #include <boost/preprocessor/repetition/enum.hpp>
0015 #include <boost/preprocessor/repetition/enum_params.hpp>
0016 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0017 #include <boost/preprocessor/iteration/local.hpp>
0018 #include <boost/preprocessor/tuple/elem.hpp>
0019 #include <boost/proto/proto_fwd.hpp> // for BOOST_PROTO_MAX_ARITY
0020 
0021 ////////////////////////////////////////////
0022 /// INTERNAL ONLY
0023 #define BOOST_PROTO_ref_a_aux(Z, N, DATA)\
0024   boost::ref(BOOST_PP_CAT(proto_a, N))
0025 
0026 /// \brief Generates a sequence like <tt>typename A0, typename A1, ...</tt>
0027 ///
0028 #define BOOST_PROTO_typename_A(N)\
0029   BOOST_PP_ENUM_PARAMS(N, typename proto_A)
0030 
0031 /// \brief Generates a sequence like <tt>A0 const &, A1 const &, ...</tt>
0032 ///
0033 #define BOOST_PROTO_A_const_ref(N)\
0034   BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const & BOOST_PP_INTERCEPT)
0035 
0036 /// \brief Generates a sequence like <tt>A0 &, A1 &, ...</tt>
0037 ///
0038 #define BOOST_PROTO_A_ref(N)\
0039   BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, & BOOST_PP_INTERCEPT)
0040 
0041 /// \brief Generates a sequence like <tt>A0, A1, ...</tt>
0042 ///
0043 #define BOOST_PROTO_A(N)\
0044   BOOST_PP_ENUM_PARAMS(N, proto_A)
0045 
0046 /// \brief Generates a sequence like <tt>A0 const, A1 const, ...</tt>
0047 ///
0048 #define BOOST_PROTO_A_const(N)\
0049   BOOST_PP_ENUM_PARAMS(N, const proto_A)
0050 
0051 /// \brief Generates a sequence like <tt>A0 const &a0, A1 const &a0, ...</tt>
0052 ///
0053 #define BOOST_PROTO_A_const_ref_a(N)\
0054   BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, const &proto_a)
0055 
0056 /// \brief Generates a sequence like <tt>A0 &a0, A1 &a0, ...</tt>
0057 ///
0058 #define BOOST_PROTO_A_ref_a(N)\
0059   BOOST_PP_ENUM_BINARY_PARAMS(N, proto_A, &proto_a)
0060 
0061 /// \brief Generates a sequence like <tt>boost::ref(a0), boost::ref(a1), ...</tt>
0062 ///
0063 #define BOOST_PROTO_ref_a(N)\
0064   BOOST_PP_ENUM(N, BOOST_PROTO_ref_a_aux, ~)
0065 
0066 /// \brief Generates a sequence like <tt>a0, a1, ...</tt>
0067 ///
0068 #define BOOST_PROTO_a(N)\
0069   BOOST_PP_ENUM_PARAMS(N, proto_a)
0070 
0071 ////////////////////////////////////////////
0072 /// INTERNAL ONLY
0073 #define BOOST_PROTO_invoke(Z, N, DATA)\
0074   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))
0075 
0076 /// \brief Repeatedly invoke the specified macro.
0077 ///
0078 /// BOOST_PROTO_REPEAT_FROM_TO_EX() is used generate the kind of repetitive code that is typical
0079 /// of EDSLs built with Proto. BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a)  is equivalent to:
0080 ///
0081 /// \code
0082 /// MACRO(FROM, typename_A, A, A_a, a)
0083 /// MACRO(FROM+1, typename_A, A, A_a, a)
0084 /// ...
0085 /// MACRO(TO-1, typename_A, A, A_a, a)
0086 /// \endcode
0087 #define BOOST_PROTO_REPEAT_FROM_TO_EX(FROM, TO, MACRO, typename_A, A, A_a, a)\
0088   BOOST_PP_REPEAT_FROM_TO(FROM, TO, BOOST_PROTO_invoke, (MACRO, typename_A, A, A_a, a))
0089 
0090 /// \brief Repeatedly invoke the specified macro.
0091 ///
0092 /// BOOST_PROTO_REPEAT_FROM_TO() is used generate the kind of repetitive code that is typical
0093 /// of EDSLs built with Proto. BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO)  is equivalent to:
0094 ///
0095 /// \code
0096 /// MACRO(FROM, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
0097 /// MACRO(FROM+1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
0098 /// ...
0099 /// MACRO(TO-1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
0100 /// \endcode
0101 ///
0102 /// Example:
0103 ///
0104 /** \code
0105 
0106 // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
0107 // following construct() function template.
0108 #define M0(N, typename_A, A_const_ref, A_const_ref_a, ref_a)      \
0109 template<typename T, typename_A(N)>                               \
0110 typename proto::result_of::make_expr<                             \
0111     proto::tag::function                                          \
0112   , construct_helper<T>                                           \
0113   , A_const_ref(N)                                                \
0114 >::type const                                                     \
0115 construct(A_const_ref_a(N))                                       \
0116 {                                                                 \
0117     return proto::make_expr<                                      \
0118         proto::tag::function                                      \
0119     >(                                                            \
0120         construct_helper<T>()                                     \
0121       , ref_a(N)                                                  \
0122     );                                                            \
0123 }
0124 BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, M0)
0125 #undef M0
0126 
0127 \endcode
0128 **/
0129 /// The above invocation of BOOST_PROTO_REPEAT_FROM_TO()  will generate
0130 /// the following code:
0131 ///
0132 /// \code
0133 /// template<typename T, typename A0>
0134 /// typename proto::result_of::make_expr<
0135 ///     proto::tag::function
0136 ///   , construct_helper<T>
0137 ///  , A0 const &
0138 /// >::type const
0139 /// construct(A0 const & a0)
0140 /// {
0141 ///     return proto::make_expr<
0142 ///         proto::tag::function
0143 ///     >(
0144 ///         construct_helper<T>()
0145 ///       , boost::ref(a0)
0146 ///     );
0147 /// }
0148 ///
0149 /// template<typename T, typename A0, typename A1>
0150 /// typename proto::result_of::make_expr<
0151 ///     proto::tag::function
0152 ///   , construct_helper<T>
0153 ///   , A0 const &
0154 ///   , A1 const &
0155 /// >::type const
0156 /// construct(A0 const & a0, A1 const & a1)
0157 /// {
0158 ///     return proto::make_expr<
0159 ///         proto::tag::function
0160 ///     >(
0161 ///         construct_helper<T>()
0162 ///       , boost::ref(a0)
0163 ///       , boost::ref(a1)
0164 ///     );
0165 /// }
0166 ///
0167 /// // ... and so on, up to BOOST_PROTO_MAX_ARITY-1 arguments ...
0168 /// \endcode
0169 #define BOOST_PROTO_REPEAT_FROM_TO(FROM, TO, MACRO)\
0170   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)
0171 
0172 /// \brief Repeatedly invoke the specified macro.
0173 ///
0174 /// BOOST_PROTO_REPEAT_EX() is used generate the kind of repetitive code that is typical
0175 /// of EDSLs built with Proto. BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a)  is equivalent to:
0176 ///
0177 /// \code
0178 /// MACRO(1, typename_A, A, A_a, a)
0179 /// MACRO(2, typename_A, A, A_a, a)
0180 /// ...
0181 /// MACRO(BOOST_PROTO_MAX_ARITY, typename_A, A, A_a, a)
0182 /// \endcode
0183 #define BOOST_PROTO_REPEAT_EX(MACRO, typename_A, A, A_a, a)\
0184   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)
0185 
0186 /// \brief Repeatedly invoke the specified macro.
0187 ///
0188 /// BOOST_PROTO_REPEAT() is used generate the kind of repetitive code that is typical
0189 /// of EDSLs built with Proto. BOOST_PROTO_REPEAT(MACRO)  is equivalent to:
0190 ///
0191 /// \code
0192 /// MACRO(1, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
0193 /// MACRO(2, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
0194 /// ...
0195 /// MACRO(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_typename_A, BOOST_PROTO_A_const_ref, BOOST_PROTO_A_const_ref_a, BOOST_PROTO_ref_a)
0196 /// \endcode
0197 #define BOOST_PROTO_REPEAT(MACRO)\
0198   BOOST_PROTO_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), MACRO)
0199 
0200 /// \brief Repeatedly invoke the specified macro.
0201 ///
0202 /// BOOST_PROTO_LOCAL_ITERATE() is used generate the kind of repetitive code that is typical
0203 /// of EDSLs built with Proto. This macro causes the user-defined macro BOOST_PROTO_LOCAL_MACRO to
0204 /// be expanded with values in the range specified by BOOST_PROTO_LOCAL_LIMITS.
0205 ///
0206 /// Usage:
0207 ///
0208 /// \code
0209 /// #include BOOST_PROTO_LOCAL_ITERATE()
0210 /// \endcode
0211 ///
0212 /// Example:
0213 ///
0214 /** \code
0215 
0216 // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
0217 // following construct() function template.
0218 #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref,       \
0219   A_const_ref_a, ref_a)                                           \
0220 template<typename T, typename_A(N)>                               \
0221 typename proto::result_of::make_expr<                             \
0222     proto::tag::function                                          \
0223   , construct_helper<T>                                           \
0224   , A_const_ref(N)                                                \
0225 >::type const                                                     \
0226 construct(A_const_ref_a(N))                                       \
0227 {                                                                 \
0228     return proto::make_expr<                                      \
0229         proto::tag::function                                      \
0230     >(                                                            \
0231         construct_helper<T>()                                     \
0232       , ref_a(N)                                                  \
0233     );                                                            \
0234 }
0235 #define BOOST_PROTO_LOCAL_LIMITS (1, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY))
0236 #include BOOST_PROTO_LOCAL_ITERATE()
0237 
0238 \endcode
0239 **/
0240 /// The above inclusion of BOOST_PROTO_LOCAL_ITERATE() will generate
0241 /// the following code:
0242 ///
0243 /// \code
0244 /// template<typename T, typename A0>
0245 /// typename proto::result_of::make_expr<
0246 ///     proto::tag::function
0247 ///   , construct_helper<T>
0248 ///  , A0 const &
0249 /// >::type const
0250 /// construct(A0 const & a0)
0251 /// {
0252 ///     return proto::make_expr<
0253 ///         proto::tag::function
0254 ///     >(
0255 ///         construct_helper<T>()
0256 ///       , boost::ref(a0)
0257 ///     );
0258 /// }
0259 ///
0260 /// template<typename T, typename A0, typename A1>
0261 /// typename proto::result_of::make_expr<
0262 ///     proto::tag::function
0263 ///   , construct_helper<T>
0264 ///   , A0 const &
0265 ///   , A1 const &
0266 /// >::type const
0267 /// construct(A0 const & a0, A1 const & a1)
0268 /// {
0269 ///     return proto::make_expr<
0270 ///         proto::tag::function
0271 ///     >(
0272 ///         construct_helper<T>()
0273 ///       , boost::ref(a0)
0274 ///       , boost::ref(a1)
0275 ///     );
0276 /// }
0277 ///
0278 /// // ... and so on, up to BOOST_PROTO_MAX_ARITY-1 arguments ...
0279 /// \endcode
0280 ///
0281 /// If BOOST_PROTO_LOCAL_LIMITS is not defined by the user, it defaults
0282 /// to (1, BOOST_PROTO_MAX_ARITY)
0283 ///
0284 /// At each iteration, BOOST_PROTO_LOCAL_MACRO is invoked with the current
0285 /// iteration number and the following 4 macro parameters:
0286 ///
0287 /// \li BOOST_PROTO_LOCAL_typename_A
0288 /// \li BOOST_PROTO_LOCAL_A
0289 /// \li BOOST_PROTO_LOCAL_A_a
0290 /// \li BOOST_PROTO_LOCAL_a
0291 ///
0292 /// If these macros are not defined by the user, they default respectively to:
0293 ///
0294 /// \li BOOST_PROTO_typename_A
0295 /// \li BOOST_PROTO_A_const_ref
0296 /// \li BOOST_PROTO_A_const_ref_a
0297 /// \li BOOST_PROTO_ref_a
0298 ///
0299 /// After including BOOST_PROTO_LOCAL_ITERATE(), the following macros are
0300 /// automatically undefined:
0301 ///
0302 /// \li BOOST_PROTO_LOCAL_MACRO
0303 /// \li BOOST_PROTO_LOCAL_LIMITS
0304 /// \li BOOST_PROTO_LOCAL_typename_A
0305 /// \li BOOST_PROTO_LOCAL_A
0306 /// \li BOOST_PROTO_LOCAL_A_a
0307 /// \li BOOST_PROTO_LOCAL_a
0308 #define BOOST_PROTO_LOCAL_ITERATE() <boost/proto/detail/local.hpp>
0309 
0310 #endif