diff options
Diffstat (limited to 'boost/proto/transform/detail/when.hpp')
-rw-r--r-- | boost/proto/transform/detail/when.hpp | 77 |
1 files changed, 34 insertions, 43 deletions
diff --git a/boost/proto/transform/detail/when.hpp b/boost/proto/transform/detail/when.hpp index 5977eff728..136210758b 100644 --- a/boost/proto/transform/detail/when.hpp +++ b/boost/proto/transform/detail/when.hpp @@ -60,50 +60,41 @@ /// ObjectTransforms. template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))> - : transform<when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))> > - { - typedef Grammar first; - typedef R second(BOOST_PP_ENUM_PARAMS(N, A)); - typedef typename Grammar::proto_grammar proto_grammar; + : detail::when_impl<Grammar, R, R(BOOST_PP_ENUM_PARAMS(N, A))> + {}; - // Note: do not evaluate is_callable<R> in this scope. - // R may be an incomplete type at this point. - - template<typename Expr, typename State, typename Data> - struct impl : transform_impl<Expr, State, Data> - { - // OK to evaluate is_callable<R> here. R should be compete by now. - typedef - typename mpl::if_c< - is_callable<R>::value - , call<R(BOOST_PP_ENUM_PARAMS(N, A))> // "R" is a function to call - , make<R(BOOST_PP_ENUM_PARAMS(N, A))> // "R" is an object to construct - >::type - which; - - typedef typename which::template impl<Expr, State, Data>::result_type result_type; - - /// Evaluate <tt>R(A0,A1,...)</tt> as a transform either with - /// <tt>call\<\></tt> or with <tt>make\<\></tt> depending on - /// whether <tt>is_callable\<R\>::value</tt> is \c true or - /// \c false. - /// - /// \param e The current expression - /// \param s The current state - /// \param d An arbitrary data - /// \pre <tt>matches\<Expr, Grammar\>::value</tt> is \c true - /// \return <tt>which()(e, s, d)</tt> - BOOST_FORCEINLINE - result_type operator ()( - typename impl::expr_param e - , typename impl::state_param s - , typename impl::data_param d - ) const - { - return typename which::template impl<Expr, State, Data>()(e, s, d); - } - }; - }; + #if N > 0 + /// \brief A grammar element and a PrimitiveTransform that associates + /// a transform with the grammar. + /// + /// Use <tt>when\<\></tt> to override a grammar's default transform + /// with a custom transform. It is for used when composing larger + /// transforms by associating smaller transforms with individual + /// rules in your grammar, as in the following transform which + /// counts the number of terminals in an expression. + /// + /// \code + /// // Count the terminals in an expression tree. + /// // Must be invoked with initial state == mpl::int_<0>(). + /// struct CountLeaves + /// : or_< + /// when<terminal<_>, mpl::next<_state>()> + /// , otherwise<fold<_, _state, CountLeaves> > + /// > + /// {}; + /// \endcode + /// + /// The <tt>when\<G, R(A0,A1,...)\></tt> form accepts either a + /// CallableTransform or an ObjectTransform as its second parameter. + /// <tt>when\<\></tt> uses <tt>is_callable\<R\>::value</tt> to + /// distinguish between the two, and uses <tt>call\<\></tt> to + /// evaluate CallableTransforms and <tt>make\<\></tt> to evaluate + /// ObjectTransforms. + template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)> + struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A)...)> + : detail::when_impl<Grammar, R, R(BOOST_PP_ENUM_PARAMS(N, A)...)> + {}; + #endif #undef N |