#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES) #include #elif !defined(BOOST_PP_IS_ITERATING) #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES) #pragma wave option(preserve: 2, line: 0, output: "preprocessed/when.hpp") #endif /////////////////////////////////////////////////////////////////////////////// /// \file when.hpp /// Definition of when transform. // // Copyright 2008 Eric Niebler. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES) #pragma wave option(preserve: 1) #endif #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PROTO_MAX_ARITY, )) #include BOOST_PP_ITERATE() #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES) #pragma wave option(output: null) #endif #else #define N BOOST_PP_ITERATION() /// \brief A grammar element and a PrimitiveTransform that associates /// a transform with the grammar. /// /// Use when\<\> 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, mpl::next<_state>()> /// , otherwise > /// > /// {}; /// \endcode /// /// The when\ form accepts either a /// CallableTransform or an ObjectTransform as its second parameter. /// when\<\> uses is_callable\::value to /// distinguish between the two, and uses call\<\> to /// evaluate CallableTransforms and make\<\> to evaluate /// ObjectTransforms. template struct when : transform > { typedef Grammar first; typedef R second(BOOST_PP_ENUM_PARAMS(N, A)); typedef typename Grammar::proto_grammar proto_grammar; // Note: do not evaluate is_callable in this scope. // R may be an incomplete type at this point. template struct impl : transform_impl { // OK to evaluate is_callable here. R should be compete by now. typedef typename mpl::if_c< is_callable::value , call // "R" is a function to call , make // "R" is an object to construct >::type which; typedef typename which::template impl::result_type result_type; /// Evaluate R(A0,A1,...) as a transform either with /// call\<\> or with make\<\> depending on /// whether is_callable\::value is \c true or /// \c false. /// /// \param e The current expression /// \param s The current state /// \param d An arbitrary data /// \pre matches\::value is \c true /// \return which()(e, s, d) result_type operator ()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { return typename which::template impl()(e, s, d); } }; }; #undef N #endif