]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/support/argument.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / spirit / home / support / argument.hpp
CommitLineData
7c673cae
FG
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>
7c673cae
FG
18#include <boost/spirit/home/support/assert_msg.hpp>
19#include <boost/spirit/home/support/limits.hpp>
20#include <boost/fusion/include/at.hpp>
21#include <boost/fusion/include/size.hpp>
22#include <boost/mpl/size.hpp>
23#include <boost/mpl/at.hpp>
f67539c2
TL
24#include <boost/phoenix/core/actor.hpp>
25#include <boost/phoenix/core/argument.hpp>
26#include <boost/phoenix/core/terminal.hpp>
27#include <boost/phoenix/core/v2_eval.hpp>
28#include <boost/proto/proto_fwd.hpp> // for transform placeholders
7c673cae
FG
29
30#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
31
32#define SPIRIT_DECLARE_ARG(z, n, data) \
33 typedef phoenix::actor<argument<n> > \
34 BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
35 phoenix::actor<argument<n> > const \
36 BOOST_PP_CAT(_, BOOST_PP_INC(n)) = \
37 BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)(); \
38 /***/
39
40#define SPIRIT_USING_ARGUMENT(z, n, data) \
41 using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \
42 using spirit::BOOST_PP_CAT(_, n); \
43 /***/
44
45#else
46
47#define SPIRIT_DECLARE_ARG(z, n, data) \
48 typedef phoenix::actor<argument<n> > \
49 BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
50 /***/
51
52#define SPIRIT_USING_ARGUMENT(z, n, data) \
53 using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \
54 /***/
55
56#endif
57
58namespace boost { namespace spirit
59{
60 template <int N>
61 struct argument;
62
63 template <typename Dummy>
64 struct attribute_context;
65}}
66
67BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
68 template <int N>
69 , boost::spirit::argument<N>
70 , mpl::false_ // is not nullary
71 , v2_eval(
72 proto::make<
73 boost::spirit::argument<N>()
74 >
75 , proto::call<
76 functional::env(proto::_state)
77 >
78 )
79)
80
81BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
82 template <typename Dummy>
83 , boost::spirit::attribute_context<Dummy>
84 , mpl::false_ // is not nullary
85 , v2_eval(
86 proto::make<
87 boost::spirit::attribute_context<Dummy>()
88 >
89 , proto::call<
90 functional::env(proto::_state)
91 >
92 )
93)
94
95namespace boost { namespace spirit
96{
97 namespace result_of
98 {
99 template <typename Sequence, int N>
100 struct get_arg
101 {
102 typedef typename
103 fusion::result_of::size<Sequence>::type
104 sequence_size;
105
106 // report invalid argument not found (N is out of bounds)
107 BOOST_SPIRIT_ASSERT_MSG(
108 (N < sequence_size::value),
109 index_is_out_of_bounds, ());
110
111 typedef typename
112 fusion::result_of::at_c<Sequence, N>::type
113 type;
114
115 static type call(Sequence& seq)
116 {
117 return fusion::at_c<N>(seq);
118 }
119 };
120
121 template <typename Sequence, int N>
122 struct get_arg<Sequence&, N> : get_arg<Sequence, N>
123 {
124 };
125 }
126
127 template <int N, typename T>
128 typename result_of::get_arg<T, N>::type
129 get_arg(T& val)
130 {
131 return result_of::get_arg<T, N>::call(val);
132 }
133
134 template <typename>
135 struct attribute_context
136 {
137 typedef mpl::true_ no_nullary;
138
139 template <typename Env>
140 struct result
141 {
142 // FIXME: is this remove_const really necessary?
143 typedef typename
144 remove_const<
145 typename mpl::at_c<typename Env::args_type, 0>::type
146 >::type
147 type;
148 };
149
150 template <typename Env>
151 typename result<Env>::type
152 eval(Env const& env) const
153 {
154 return fusion::at_c<0>(env.args());
155 }
156 };
157
158 template <int N>
159 struct argument
160 {
161 typedef mpl::true_ no_nullary;
162
163 template <typename Env>
164 struct result
165 {
166 typedef typename
167 mpl::at_c<typename Env::args_type, 0>::type
168 arg_type;
169
170 typedef typename result_of::get_arg<arg_type, N>::type type;
171 };
172
173 template <typename Env>
174 typename result<Env>::type
175 eval(Env const& env) const
176 {
177 return get_arg<N>(fusion::at_c<0>(env.args()));
178 }
179 };
180
181 // _0 refers to the whole attribute as generated by the lhs parser
182 typedef phoenix::actor<attribute_context<void> > _0_type;
183#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
184 _0_type const _0 = _0_type();
185#endif
186
187 // _1, _2, ... refer to the attributes of the single components the lhs
188 // parser is composed of
189 typedef phoenix::actor<argument<0> > _1_type;
190 typedef phoenix::actor<argument<1> > _2_type;
191 typedef phoenix::actor<argument<2> > _3_type;
192
193#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
194 _1_type const _1 = _1_type();
195 _2_type const _2 = _2_type();
196 _3_type const _3 = _3_type();
197#endif
198
199 // '_pass' may be used to make a match fail in retrospective
200 typedef phoenix::arg_names::_3_type _pass_type;
201#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
202 _pass_type const _pass = _pass_type();
203#endif
204
205 // Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP
206 BOOST_PP_REPEAT_FROM_TO(
207 3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _)
208
209#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
210 // You can bring these in with the using directive
211 // without worrying about bringing in too much.
212 namespace labels
213 {
214 BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
215 }
216#endif
217
218}}
219
220#undef SPIRIT_DECLARE_ARG
221#endif