Chris@16: #if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES) Chris@16: Chris@16: #include Chris@16: Chris@16: #elif !defined(BOOST_PP_IS_ITERATING) Chris@16: Chris@16: #define BOOST_PROTO_CHILD(Z, N, DATA) \ Chris@16: /** INTERNAL ONLY */ \ Chris@16: typedef BOOST_PP_CAT(DATA, N) BOOST_PP_CAT(proto_child, N); \ Chris@16: /**/ Chris@16: Chris@16: #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES) Chris@16: #pragma wave option(preserve: 2, line: 0, output: "preprocessed/traits.hpp") Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file traits.hpp Chris@16: /// Definitions of proto::function, proto::nary_expr and proto::result_of::child_c Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES) Chris@16: #pragma wave option(preserve: 1) Chris@16: #endif Chris@16: Chris@16: #define BOOST_PP_ITERATION_PARAMS_1 \ Chris@16: (3, (0, BOOST_PROTO_MAX_ARITY, )) Chris@16: #include BOOST_PP_ITERATE() Chris@16: Chris@16: #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES) Chris@16: #pragma wave option(output: null) Chris@16: #endif Chris@16: Chris@16: #undef BOOST_PROTO_CHILD Chris@16: Chris@16: #else // BOOST_PP_IS_ITERATING Chris@16: Chris@16: #define N BOOST_PP_ITERATION() Chris@16: Chris@16: #if N > 0 Chris@16: /// \brief A metafunction for generating function-call expression types, Chris@16: /// a grammar element for matching function-call expressions, and a Chris@16: /// PrimitiveTransform that dispatches to the pass_through\<\> Chris@16: /// transform. Chris@16: template Chris@16: struct function Chris@16: #if N != BOOST_PROTO_MAX_ARITY Chris@16: < Chris@16: BOOST_PP_ENUM_PARAMS(N, A) Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT) Chris@16: > Chris@16: #endif Chris@16: : proto::transform< Chris@16: function< Chris@16: BOOST_PP_ENUM_PARAMS(N, A) Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT) Chris@16: > Chris@16: , int Chris@16: > Chris@16: { Chris@16: typedef proto::expr, N> type; Chris@16: typedef proto::basic_expr, N> proto_grammar; Chris@16: Chris@16: template Chris@16: struct impl Chris@16: : detail::pass_through_impl Chris@16: {}; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: typedef proto::tag::function proto_tag; Chris@16: BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A) Chris@16: BOOST_PP_REPEAT_FROM_TO( Chris@16: N Chris@16: , BOOST_PROTO_MAX_ARITY Chris@16: , BOOST_PROTO_CHILD Chris@16: , detail::if_vararg BOOST_PP_INTERCEPT Chris@16: ) Chris@16: }; Chris@16: Chris@16: /// \brief A metafunction for generating n-ary expression types with a Chris@16: /// specified tag type, Chris@16: /// a grammar element for matching n-ary expressions, and a Chris@16: /// PrimitiveTransform that dispatches to the pass_through\<\> Chris@16: /// transform. Chris@16: /// Chris@16: /// Use nary_expr\<_, vararg\<_\> \> as a grammar element to match any Chris@16: /// n-ary expression; that is, any non-terminal. Chris@16: template Chris@16: struct nary_expr Chris@16: #if N != BOOST_PROTO_MAX_ARITY Chris@16: < Chris@16: Tag Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS(N, A) Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT) Chris@16: > Chris@16: #endif Chris@16: : proto::transform< Chris@16: nary_expr< Chris@16: Tag Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS(N, A) Chris@16: BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT) Chris@16: > Chris@16: , int Chris@16: > Chris@16: { Chris@16: typedef proto::expr, N> type; Chris@16: typedef proto::basic_expr, N> proto_grammar; Chris@16: Chris@16: template Chris@16: struct impl Chris@16: : detail::pass_through_impl Chris@16: {}; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: typedef Tag proto_tag; Chris@16: BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A) Chris@16: BOOST_PP_REPEAT_FROM_TO( Chris@16: N Chris@16: , BOOST_PROTO_MAX_ARITY Chris@16: , BOOST_PROTO_CHILD Chris@16: , detail::if_vararg BOOST_PP_INTERCEPT Chris@16: ) Chris@16: }; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: template< Chris@16: template class T Chris@16: , BOOST_PP_ENUM_PARAMS(N, typename A) Chris@16: > Chris@16: struct is_callable_ BOOST_PROTO_TEMPLATE_ARITY_PARAM(N)> Chris@16: : is_same Chris@16: {}; Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace result_of Chris@16: { Chris@16: /// \brief A metafunction that returns the type of the Nth child Chris@16: /// of a Proto expression. Chris@16: /// Chris@16: /// A metafunction that returns the type of the Nth child Chris@16: /// of a Proto expression. \c N must be less than Chris@16: /// \c Expr::proto_arity::value. Chris@16: template Chris@16: struct child_c Chris@16: { Chris@16: /// Verify that we are not operating on a terminal Chris@16: BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c); Chris@16: Chris@16: /// The raw type of the Nth child as it is stored within Chris@16: /// \c Expr. This may be a value or a reference Chris@16: typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type; Chris@16: Chris@16: /// The "value" type of the child, suitable for return by value, Chris@16: /// computed as follows: Chris@16: /// \li T const & becomes T Chris@16: /// \li T & becomes T Chris@16: /// \li T becomes T Chris@16: typedef typename detail::expr_traits::value_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct child_c Chris@16: { Chris@16: /// Verify that we are not operating on a terminal Chris@16: BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c); Chris@16: Chris@16: /// The raw type of the Nth child as it is stored within Chris@16: /// \c Expr. This may be a value or a reference Chris@16: typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type; Chris@16: Chris@16: /// The "reference" type of the child, suitable for return by Chris@16: /// reference, computed as follows: Chris@16: /// \li T const & becomes T const & Chris@16: /// \li T & becomes T & Chris@16: /// \li T becomes T & Chris@16: typedef typename detail::expr_traits::reference type; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: BOOST_FORCEINLINE Chris@16: static type call(Expr &e) Chris@16: { Chris@16: return e.proto_base().BOOST_PP_CAT(child, N); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct child_c Chris@16: { Chris@16: /// Verify that we are not operating on a terminal Chris@16: BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c); Chris@16: Chris@16: /// The raw type of the Nth child as it is stored within Chris@16: /// \c Expr. This may be a value or a reference Chris@16: typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type; Chris@16: Chris@16: /// The "const reference" type of the child, suitable for return by Chris@16: /// const reference, computed as follows: Chris@16: /// \li T const & becomes T const & Chris@16: /// \li T & becomes T & Chris@16: /// \li T becomes T const & Chris@16: typedef typename detail::expr_traits::const_reference type; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: BOOST_FORCEINLINE Chris@16: static type call(Expr const &e) Chris@16: { Chris@16: return e.proto_base().BOOST_PP_CAT(child, N); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: #undef N Chris@16: Chris@16: #endif