Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: Copyright (c) 2011 Thomas Heller Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM) Chris@16: #define BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: Chris@16: #define SPIRIT_DECLARE_ARG(z, n, data) \ Chris@16: typedef phoenix::actor > \ Chris@16: BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ Chris@16: phoenix::actor > const \ Chris@16: BOOST_PP_CAT(_, BOOST_PP_INC(n)) = \ Chris@16: BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)(); \ Chris@16: /***/ Chris@16: Chris@16: #define SPIRIT_USING_ARGUMENT(z, n, data) \ Chris@16: using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ Chris@16: using spirit::BOOST_PP_CAT(_, n); \ Chris@16: /***/ Chris@16: Chris@16: #else Chris@16: Chris@16: #define SPIRIT_DECLARE_ARG(z, n, data) \ Chris@16: typedef phoenix::actor > \ Chris@16: BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ Chris@16: /***/ Chris@16: Chris@16: #define SPIRIT_USING_ARGUMENT(z, n, data) \ Chris@16: using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ Chris@16: /***/ Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: template Chris@16: struct argument; Chris@16: Chris@16: template Chris@16: struct attribute_context; Chris@16: }} Chris@16: Chris@16: BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( Chris@16: template Chris@16: , boost::spirit::argument Chris@16: , mpl::false_ // is not nullary Chris@16: , v2_eval( Chris@16: proto::make< Chris@16: boost::spirit::argument() Chris@16: > Chris@16: , proto::call< Chris@16: functional::env(proto::_state) Chris@16: > Chris@16: ) Chris@16: ) Chris@16: Chris@16: BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( Chris@16: template Chris@16: , boost::spirit::attribute_context Chris@16: , mpl::false_ // is not nullary Chris@16: , v2_eval( Chris@16: proto::make< Chris@16: boost::spirit::attribute_context() Chris@16: > Chris@16: , proto::call< Chris@16: functional::env(proto::_state) Chris@16: > Chris@16: ) Chris@16: ) Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: namespace result_of Chris@16: { Chris@16: template Chris@16: struct get_arg Chris@16: { Chris@16: typedef typename Chris@16: fusion::result_of::size::type Chris@16: sequence_size; Chris@16: Chris@16: // report invalid argument not found (N is out of bounds) Chris@16: BOOST_SPIRIT_ASSERT_MSG( Chris@16: (N < sequence_size::value), Chris@16: index_is_out_of_bounds, ()); Chris@16: Chris@16: typedef typename Chris@16: fusion::result_of::at_c::type Chris@16: type; Chris@16: Chris@16: static type call(Sequence& seq) Chris@16: { Chris@16: return fusion::at_c(seq); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct get_arg : get_arg Chris@16: { Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: typename result_of::get_arg::type Chris@16: get_arg(T& val) Chris@16: { Chris@16: return result_of::get_arg::call(val); Chris@16: } Chris@16: Chris@16: template Chris@16: struct attribute_context Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: // FIXME: is this remove_const really necessary? Chris@16: typedef typename Chris@16: remove_const< Chris@16: typename mpl::at_c::type Chris@16: >::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return fusion::at_c<0>(env.args()); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct argument Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Chris@16: mpl::at_c::type Chris@16: arg_type; Chris@16: Chris@16: typedef typename result_of::get_arg::type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return get_arg(fusion::at_c<0>(env.args())); Chris@16: } Chris@16: }; Chris@16: Chris@16: // _0 refers to the whole attribute as generated by the lhs parser Chris@16: typedef phoenix::actor > _0_type; Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: _0_type const _0 = _0_type(); Chris@16: #endif Chris@16: Chris@16: // _1, _2, ... refer to the attributes of the single components the lhs Chris@16: // parser is composed of Chris@16: typedef phoenix::actor > _1_type; Chris@16: typedef phoenix::actor > _2_type; Chris@16: typedef phoenix::actor > _3_type; Chris@16: Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: _1_type const _1 = _1_type(); Chris@16: _2_type const _2 = _2_type(); Chris@16: _3_type const _3 = _3_type(); Chris@16: #endif Chris@16: Chris@16: // '_pass' may be used to make a match fail in retrospective Chris@16: typedef phoenix::arg_names::_3_type _pass_type; Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: _pass_type const _pass = _pass_type(); Chris@16: #endif Chris@16: Chris@16: // Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP Chris@16: BOOST_PP_REPEAT_FROM_TO( Chris@16: 3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _) Chris@16: Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: // You can bring these in with the using directive Chris@16: // without worrying about bringing in too much. Chris@16: namespace labels Chris@16: { Chris@16: BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _) Chris@16: } Chris@16: #endif Chris@16: Chris@16: }} Chris@16: Chris@16: #undef SPIRIT_DECLARE_ARG Chris@16: #endif