Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/spirit/home/support/argument.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004     Copyright (c)      2011 Thomas Heller
0005 
0006     Distributed under the Boost Software License, Version 1.0. (See accompanying
0007     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 ==============================================================================*/
0009 #if !defined(BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM)
0010 #define BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
0017 #include <boost/preprocessor/arithmetic/inc.hpp>
0018 #include <boost/spirit/home/support/assert_msg.hpp>
0019 #include <boost/spirit/home/support/limits.hpp>
0020 #include <boost/fusion/include/at.hpp>
0021 #include <boost/fusion/include/size.hpp>
0022 #include <boost/mpl/size.hpp>
0023 #include <boost/mpl/at.hpp>
0024 #include <boost/phoenix/core/actor.hpp>
0025 #include <boost/phoenix/core/argument.hpp>
0026 #include <boost/phoenix/core/terminal.hpp>
0027 #include <boost/phoenix/core/v2_eval.hpp>
0028 #include <boost/proto/proto_fwd.hpp> // for transform placeholders
0029 
0030 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0031 
0032 #define SPIRIT_DECLARE_ARG(z, n, data)                                        \
0033     typedef phoenix::actor<argument<n> >                                      \
0034         BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type);                \
0035     phoenix::actor<argument<n> > const                                        \
0036         BOOST_PP_CAT(_, BOOST_PP_INC(n)) =                                    \
0037             BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)();          \
0038         /***/
0039 
0040 #define SPIRIT_USING_ARGUMENT(z, n, data)                                     \
0041     using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type);                    \
0042     using spirit::BOOST_PP_CAT(_, n);                                         \
0043         /***/
0044 
0045 #else
0046 
0047 #define SPIRIT_DECLARE_ARG(z, n, data)                                        \
0048     typedef phoenix::actor<argument<n> >                                      \
0049         BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type);                \
0050         /***/
0051 
0052 #define SPIRIT_USING_ARGUMENT(z, n, data)                                     \
0053     using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type);                    \
0054         /***/
0055 
0056 #endif
0057 
0058 namespace boost { namespace spirit
0059 {
0060     template <int N>
0061     struct argument;
0062 
0063     template <typename Dummy>
0064     struct attribute_context;
0065 }}
0066 
0067 BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
0068     template <int N>
0069   , boost::spirit::argument<N>
0070   , mpl::false_                 // is not nullary
0071   , v2_eval(
0072         proto::make<
0073             boost::spirit::argument<N>()
0074         >
0075       , proto::call<
0076             functional::env(proto::_state)
0077         >
0078     )
0079 )
0080 
0081 BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
0082     template <typename Dummy>
0083   , boost::spirit::attribute_context<Dummy>
0084   , mpl::false_                 // is not nullary
0085   , v2_eval(
0086         proto::make<
0087             boost::spirit::attribute_context<Dummy>()
0088         >
0089       , proto::call<
0090             functional::env(proto::_state)
0091         >
0092     )
0093 )
0094 
0095 namespace boost { namespace spirit
0096 {
0097     namespace result_of
0098     {
0099         template <typename Sequence, int N>
0100         struct get_arg
0101         {
0102             typedef typename
0103                 fusion::result_of::size<Sequence>::type
0104             sequence_size;
0105 
0106             // report invalid argument not found (N is out of bounds)
0107             BOOST_SPIRIT_ASSERT_MSG(
0108                 (N < sequence_size::value),
0109                 index_is_out_of_bounds, ());
0110 
0111             typedef typename
0112                 fusion::result_of::at_c<Sequence, N>::type
0113             type;
0114 
0115             static type call(Sequence& seq)
0116             {
0117                 return fusion::at_c<N>(seq);
0118             }
0119         };
0120 
0121         template <typename Sequence, int N>
0122         struct get_arg<Sequence&, N> : get_arg<Sequence, N>
0123         {
0124         };
0125     }
0126 
0127     template <int N, typename T>
0128     typename result_of::get_arg<T, N>::type
0129     get_arg(T& val)
0130     {
0131         return result_of::get_arg<T, N>::call(val);
0132     }
0133 
0134     template <typename>
0135     struct attribute_context
0136     {
0137         typedef mpl::true_ no_nullary;
0138 
0139         template <typename Env>
0140         struct result
0141         {
0142             // FIXME: is this remove_const really necessary?
0143             typedef typename
0144                 remove_const<
0145                     typename mpl::at_c<typename Env::args_type, 0>::type
0146                 >::type
0147             type;
0148         };
0149 
0150         template <typename Env>
0151         typename result<Env>::type
0152         eval(Env const& env) const
0153         {
0154             return fusion::at_c<0>(env.args());
0155         }
0156     };
0157 
0158     template <int N>
0159     struct argument
0160     {
0161         typedef mpl::true_ no_nullary;
0162 
0163         template <typename Env>
0164         struct result
0165         {
0166             typedef typename
0167                 mpl::at_c<typename Env::args_type, 0>::type
0168             arg_type;
0169 
0170             typedef typename result_of::get_arg<arg_type, N>::type type;
0171         };
0172 
0173         template <typename Env>
0174         typename result<Env>::type
0175         eval(Env const& env) const
0176         {
0177             return get_arg<N>(fusion::at_c<0>(env.args()));
0178         }
0179     };
0180 
0181     // _0 refers to the whole attribute as generated by the lhs parser
0182     typedef phoenix::actor<attribute_context<void> > _0_type;
0183 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0184     _0_type const _0 = _0_type();
0185 #endif
0186 
0187     // _1, _2, ... refer to the attributes of the single components the lhs
0188     // parser is composed of
0189     typedef phoenix::actor<argument<0> > _1_type;
0190     typedef phoenix::actor<argument<1> > _2_type;
0191     typedef phoenix::actor<argument<2> > _3_type;
0192 
0193 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0194     _1_type const _1 = _1_type();
0195     _2_type const _2 = _2_type();
0196     _3_type const _3 = _3_type();
0197 #endif
0198 
0199     // '_pass' may be used to make a match fail in retrospective
0200     typedef phoenix::arg_names::_3_type _pass_type;
0201 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0202     _pass_type const _pass = _pass_type();
0203 #endif
0204 
0205     //  Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP
0206     BOOST_PP_REPEAT_FROM_TO(
0207         3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _)
0208 
0209 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0210     // You can bring these in with the using directive
0211     // without worrying about bringing in too much.
0212     namespace labels
0213     {
0214         BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
0215     }
0216 #endif
0217 
0218 }}
0219 
0220 #undef SPIRIT_DECLARE_ARG
0221 #endif