PageRenderTime 29ms CodeModel.GetById 18ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/support/argument.hpp

http://hadesmem.googlecode.com/
C++ Header | 217 lines | 162 code | 34 blank | 21 comment | 0 complexity | 3a83e30e9844068f838e3f0f7d4ad739 MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2001-2011 Joel de Guzman
  3    Copyright (c) 2001-2011 Hartmut Kaiser
  4    Copyright (c)      2011 Thomas Heller
  5
  6    Distributed under the Boost Software License, Version 1.0. (See accompanying
  7    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8==============================================================================*/
  9#if !defined(BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM)
 10#define BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM
 11
 12#if defined(_MSC_VER)
 13#pragma once
 14#endif
 15
 16#include <boost/preprocessor/repetition/repeat_from_to.hpp>
 17#include <boost/preprocessor/arithmetic/inc.hpp>
 18#include <boost/spirit/include/phoenix_core.hpp>
 19#include <boost/spirit/home/support/assert_msg.hpp>
 20#include <boost/spirit/home/support/limits.hpp>
 21#include <boost/fusion/include/at.hpp>
 22#include <boost/fusion/include/size.hpp>
 23#include <boost/mpl/size.hpp>
 24#include <boost/mpl/at.hpp>
 25
 26#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
 27
 28#define SPIRIT_DECLARE_ARG(z, n, data)                                        \
 29    typedef phoenix::actor<argument<n> >                                      \
 30        BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type);                \
 31    phoenix::actor<argument<n> > const                                        \
 32        BOOST_PP_CAT(_, BOOST_PP_INC(n)) =                                    \
 33            BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)();          \
 34        /***/
 35
 36#define SPIRIT_USING_ARGUMENT(z, n, data)                                     \
 37    using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type);                    \
 38    using spirit::BOOST_PP_CAT(_, n);                                         \
 39        /***/
 40
 41#else
 42
 43#define SPIRIT_DECLARE_ARG(z, n, data)                                        \
 44    typedef phoenix::actor<argument<n> >                                      \
 45        BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type);                \
 46        /***/
 47
 48#define SPIRIT_USING_ARGUMENT(z, n, data)                                     \
 49    using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type);                    \
 50        /***/
 51
 52#endif
 53
 54namespace boost { namespace spirit
 55{
 56    template <int N>
 57    struct argument;
 58
 59    template <typename Dummy>
 60    struct attribute_context;
 61}}
 62
 63BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
 64    template <int N>
 65  , boost::spirit::argument<N>
 66  , mpl::false_                 // is not nullary
 67  , v2_eval(
 68        proto::make<
 69            boost::spirit::argument<N>()
 70        >
 71      , proto::call<
 72            functional::env(proto::_state)
 73        >
 74    )
 75)
 76
 77BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
 78    template <typename Dummy>
 79  , boost::spirit::attribute_context<Dummy>
 80  , mpl::false_                 // is not nullary
 81  , v2_eval(
 82        proto::make<
 83            boost::spirit::attribute_context<Dummy>()
 84        >
 85      , proto::call<
 86            functional::env(proto::_state)
 87        >
 88    )
 89)
 90
 91namespace boost { namespace spirit
 92{
 93    namespace result_of
 94    {
 95        template <typename Sequence, int N>
 96        struct get_arg
 97        {
 98            typedef typename
 99                fusion::result_of::size<Sequence>::type
100            sequence_size;
101
102            // report invalid argument not found (N is out of bounds)
103            BOOST_SPIRIT_ASSERT_MSG(
104                (N < sequence_size::value),
105                index_is_out_of_bounds, ());
106
107            typedef typename
108                fusion::result_of::at_c<Sequence, N>::type
109            type;
110
111            static type call(Sequence& seq)
112            {
113                return fusion::at_c<N>(seq);
114            }
115        };
116
117        template <typename Sequence, int N>
118        struct get_arg<Sequence&, N> : get_arg<Sequence, N>
119        {
120        };
121    }
122
123    template <int N, typename T>
124    typename result_of::get_arg<T, N>::type
125    get_arg(T& val)
126    {
127        return result_of::get_arg<T, N>::call(val);
128    }
129
130    template <typename>
131    struct attribute_context
132    {
133        typedef mpl::true_ no_nullary;
134
135        template <typename Env>
136        struct result
137        {
138            // FIXME: is this remove_const really necessary?
139            typedef typename
140                remove_const<
141                    typename mpl::at_c<typename Env::args_type, 0>::type
142                >::type
143            type;
144        };
145
146        template <typename Env>
147        typename result<Env>::type
148        eval(Env const& env) const
149        {
150            return fusion::at_c<0>(env.args());
151        }
152    };
153
154    template <int N>
155    struct argument
156    {
157        typedef mpl::true_ no_nullary;
158
159        template <typename Env>
160        struct result
161        {
162            typedef typename
163                mpl::at_c<typename Env::args_type, 0>::type
164            arg_type;
165
166            typedef typename result_of::get_arg<arg_type, N>::type type;
167        };
168
169        template <typename Env>
170        typename result<Env>::type
171        eval(Env const& env) const
172        {
173            return get_arg<N>(fusion::at_c<0>(env.args()));
174        }
175    };
176
177    // _0 refers to the whole attribute as generated by the lhs parser
178    typedef phoenix::actor<attribute_context<void> > _0_type;
179#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
180    _0_type const _0 = _0_type();
181#endif
182
183    // _1, _2, ... refer to the attributes of the single components the lhs
184    // parser is composed of
185    typedef phoenix::actor<argument<0> > _1_type;
186    typedef phoenix::actor<argument<1> > _2_type;
187    typedef phoenix::actor<argument<2> > _3_type;
188
189#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
190    _1_type const _1 = _1_type();
191    _2_type const _2 = _2_type();
192    _3_type const _3 = _3_type();
193#endif
194
195    // '_pass' may be used to make a match fail in retrospective
196    typedef phoenix::arg_names::_3_type _pass_type;
197#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
198    _pass_type const _pass = _pass_type();
199#endif
200
201    //  Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP
202    BOOST_PP_REPEAT_FROM_TO(
203        3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _)
204
205#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
206    // You can bring these in with the using directive
207    // without worrying about bringing in too much.
208    namespace labels
209    {
210        BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
211    }
212#endif
213
214}}
215
216#undef SPIRIT_DECLARE_ARG
217#endif