EVOLUTION-MANAGER
Edit File: argument.hpp
/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Copyright (c) 2011 Thomas Heller 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(BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM) #define BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM #if defined(_MSC_VER) #pragma once #endif #include <boost/preprocessor/repetition/repeat_from_to.hpp> #include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/home/support/assert_msg.hpp> #include <boost/spirit/home/support/limits.hpp> #include <boost/fusion/include/at.hpp> #include <boost/fusion/include/size.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/at.hpp> #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS #define SPIRIT_DECLARE_ARG(z, n, data) \ typedef phoenix::actor<argument<n> > \ BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ phoenix::actor<argument<n> > const \ BOOST_PP_CAT(_, BOOST_PP_INC(n)) = \ BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)(); \ /***/ #define SPIRIT_USING_ARGUMENT(z, n, data) \ using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ using spirit::BOOST_PP_CAT(_, n); \ /***/ #else #define SPIRIT_DECLARE_ARG(z, n, data) \ typedef phoenix::actor<argument<n> > \ BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \ /***/ #define SPIRIT_USING_ARGUMENT(z, n, data) \ using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \ /***/ #endif namespace boost { namespace spirit { template <int N> struct argument; template <typename Dummy> struct attribute_context; }} BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( template <int N> , boost::spirit::argument<N> , mpl::false_ // is not nullary , v2_eval( proto::make< boost::spirit::argument<N>() > , proto::call< functional::env(proto::_state) > ) ) BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( template <typename Dummy> , boost::spirit::attribute_context<Dummy> , mpl::false_ // is not nullary , v2_eval( proto::make< boost::spirit::attribute_context<Dummy>() > , proto::call< functional::env(proto::_state) > ) ) namespace boost { namespace spirit { namespace result_of { template <typename Sequence, int N> struct get_arg { typedef typename fusion::result_of::size<Sequence>::type sequence_size; // report invalid argument not found (N is out of bounds) BOOST_SPIRIT_ASSERT_MSG( (N < sequence_size::value), index_is_out_of_bounds, ()); typedef typename fusion::result_of::at_c<Sequence, N>::type type; static type call(Sequence& seq) { return fusion::at_c<N>(seq); } }; template <typename Sequence, int N> struct get_arg<Sequence&, N> : get_arg<Sequence, N> { }; } template <int N, typename T> typename result_of::get_arg<T, N>::type get_arg(T& val) { return result_of::get_arg<T, N>::call(val); } template <typename> struct attribute_context { typedef mpl::true_ no_nullary; template <typename Env> struct result { // FIXME: is this remove_const really necessary? typedef typename remove_const< typename mpl::at_c<typename Env::args_type, 0>::type >::type type; }; template <typename Env> typename result<Env>::type eval(Env const& env) const { return fusion::at_c<0>(env.args()); } }; template <int N> struct argument { typedef mpl::true_ no_nullary; template <typename Env> struct result { typedef typename mpl::at_c<typename Env::args_type, 0>::type arg_type; typedef typename result_of::get_arg<arg_type, N>::type type; }; template <typename Env> typename result<Env>::type eval(Env const& env) const { return get_arg<N>(fusion::at_c<0>(env.args())); } }; // _0 refers to the whole attribute as generated by the lhs parser typedef phoenix::actor<attribute_context<void> > _0_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS _0_type const _0 = _0_type(); #endif // _1, _2, ... refer to the attributes of the single components the lhs // parser is composed of typedef phoenix::actor<argument<0> > _1_type; typedef phoenix::actor<argument<1> > _2_type; typedef phoenix::actor<argument<2> > _3_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS _1_type const _1 = _1_type(); _2_type const _2 = _2_type(); _3_type const _3 = _3_type(); #endif // '_pass' may be used to make a match fail in retrospective typedef phoenix::arg_names::_3_type _pass_type; #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS _pass_type const _pass = _pass_type(); #endif // Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP BOOST_PP_REPEAT_FROM_TO( 3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _) #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS // You can bring these in with the using directive // without worrying about bringing in too much. namespace labels { BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _) } #endif }} #undef SPIRIT_DECLARE_ARG #endif