]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/metaparse/example/meta_metaparse/main.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / metaparse / example / meta_metaparse / main.cpp
1 // Copyright Abel Sinkovics (abel@sinkovics.hu) 2012.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 #define BOOST_MPL_LIMIT_STRING_SIZE 64
7 #define BOOST_METAPARSE_LIMIT_STRING_SIZE BOOST_MPL_LIMIT_STRING_SIZE
8
9 #include <boost/metaparse/grammar.hpp>
10
11 #include <boost/metaparse/string.hpp>
12 #include <boost/metaparse/build_parser.hpp>
13 #include <boost/metaparse/token.hpp>
14 #include <boost/metaparse/entire_input.hpp>
15 #include <boost/metaparse/int_.hpp>
16 #include <boost/metaparse/transform.hpp>
17
18 #include <boost/mpl/apply_wrap.hpp>
19 #include <boost/mpl/front.hpp>
20 #include <boost/mpl/back.hpp>
21 #include <boost/mpl/if.hpp>
22 #include <boost/mpl/bool.hpp>
23 #include <boost/mpl/fold.hpp>
24
25 using boost::mpl::apply_wrap1;
26 using boost::mpl::front;
27 using boost::mpl::back;
28 using boost::mpl::if_;
29 using boost::mpl::bool_;
30
31 using boost::metaparse::build_parser;
32 using boost::metaparse::token;
33 using boost::metaparse::entire_input;
34 using boost::metaparse::int_;
35 using boost::metaparse::grammar;
36 using boost::metaparse::transform;
37
38 #if BOOST_METAPARSE_STD < 2011
39 int main()
40 {
41 std::cout << "Please use a compiler that supports constexpr" << std::endl;
42 }
43 #else
44
45 #ifdef _STR
46 # error _STR already defined
47 #endif
48 #define _STR BOOST_METAPARSE_STRING
49
50 template <class T, char C>
51 struct is_c : bool_<T::type::value == C> {};
52
53 struct build_plus_impl
54 {
55 template <class A, class B>
56 class _plus
57 {
58 public:
59 typedef _plus type;
60
61 template <class T>
62 T operator()(T t) const
63 {
64 return _left(t) + _right(t);
65 }
66 private:
67 typename A::type _left;
68 typename B::type _right;
69 };
70
71 template <class A, class B>
72 class _minus
73 {
74 public:
75 typedef _minus type;
76
77 template <class T>
78 T operator()(T t) const
79 {
80 return _left(t) - _right(t);
81 }
82 private:
83 typename A::type _left;
84 typename B::type _right;
85 };
86
87 template <class State, class C>
88 struct apply :
89 if_<
90 typename is_c<front<C>, '+'>::type,
91 _plus<State, typename back<C>::type>,
92 _minus<State, typename back<C>::type>
93 >
94 {};
95 };
96
97 struct build_plus
98 {
99 typedef build_plus type;
100
101 template <class Seq>
102 struct apply :
103 boost::mpl::fold<
104 typename back<Seq>::type,
105 typename front<Seq>::type,
106 build_plus_impl
107 >
108 {};
109 };
110
111 struct build_mult_impl
112 {
113 template <class A, class B>
114 class _mult
115 {
116 public:
117 typedef _mult type;
118
119 template <class T>
120 T operator()(T t) const
121 {
122 return _left(t) * _right(t);
123 }
124 private:
125 typename A::type _left;
126 typename B::type _right;
127 };
128
129 template <class A, class B>
130 class _div
131 {
132 public:
133 typedef _div type;
134
135 template <class T>
136 T operator()(T t) const
137 {
138 return _left(t) / _right(t);
139 }
140 private:
141 typename A::type _left;
142 typename B::type _right;
143 };
144
145 template <class State, class C>
146 struct apply :
147 if_<
148 typename is_c<front<C>, '*'>::type,
149 _mult<State, typename back<C>::type>,
150 _div<State, typename back<C>::type>
151 >
152 {};
153 };
154
155 struct build_mult
156 {
157 typedef build_mult type;
158
159 template <class Seq>
160 struct apply :
161 boost::mpl::fold<
162 typename back<Seq>::type,
163 typename front<Seq>::type,
164 build_mult_impl
165 >
166 {};
167 };
168
169 struct build_value
170 {
171 typedef build_value type;
172
173 template <class V>
174 struct apply
175 {
176 typedef apply type;
177
178 template <class T>
179 int operator()(T) const
180 {
181 return V::type::value;
182 }
183 };
184 };
185
186 struct build_arg
187 {
188 typedef build_arg type;
189
190 template <class>
191 struct apply
192 {
193 typedef apply type;
194
195 template <class T>
196 T operator()(T t) const
197 {
198 return t;
199 }
200 };
201 };
202
203 struct keep_front
204 {
205 typedef keep_front type;
206
207 template <class Seq>
208 struct apply : front<Seq> {};
209 };
210
211 typedef
212 grammar<_STR("plus_exp")>
213 ::import<_STR("int_token"), token<transform<int_, build_value>>>::type
214
215 ::rule<_STR("ws ::= (' ' | '\n' | '\r' | '\t')*")>::type
216 ::rule<_STR("plus_token ::= '+' ws"), keep_front>::type
217 ::rule<_STR("minus_token ::= '-' ws"), keep_front>::type
218 ::rule<_STR("mult_token ::= '*' ws"), keep_front>::type
219 ::rule<_STR("div_token ::= '/' ws"), keep_front>::type
220 ::rule<_STR("arg_token ::= '_' ws"), keep_front>::type
221
222 ::rule<_STR("plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*"), build_plus>::type
223 ::rule<_STR("prod_exp ::= value_exp ((mult_token | div_token) value_exp)*"), build_mult>::type
224 ::rule<_STR("value_exp ::= int_token | arg_exp")>::type
225 ::rule<_STR("arg_exp ::= arg_token"), build_arg>::type
226 g;
227
228 typedef build_parser<entire_input<g>> function_parser;
229
230 #ifdef LAMBDA
231 #error LAMBDA already defined
232 #endif
233 #define LAMBDA(exp) apply_wrap1<function_parser, _STR(#exp)>::type
234
235 LAMBDA(13) f1;
236 LAMBDA(2 + 3) f2;
237 LAMBDA(2 * 3) f3;
238 LAMBDA(1+ 2*4-6/2) f4;
239 LAMBDA(2 * _) f5;
240
241 int main()
242 {
243 using std::cout;
244 using std::endl;
245
246 cout
247 << f1(11) << endl
248 << f2(11) << endl
249 << f3(11) << endl
250 << f4(11) << endl
251 << f5(11) << endl
252 << f5(1.1) << endl
253 ;
254 }
255
256 #endif
257
258