]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/metaparse/example/meta_lambda/main.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / metaparse / example / meta_lambda / 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 #include <boost/metaparse/repeated.hpp>
7 #include <boost/metaparse/sequence.hpp>
8 #include <boost/metaparse/lit_c.hpp>
9 #include <boost/metaparse/last_of.hpp>
10 #include <boost/metaparse/space.hpp>
11 #include <boost/metaparse/int_.hpp>
12 #include <boost/metaparse/foldl_reject_incomplete_start_with_parser.hpp>
13 #include <boost/metaparse/one_of.hpp>
14 #include <boost/metaparse/get_result.hpp>
15 #include <boost/metaparse/token.hpp>
16 #include <boost/metaparse/entire_input.hpp>
17 #include <boost/metaparse/string.hpp>
18 #include <boost/metaparse/transform.hpp>
19 #include <boost/metaparse/always.hpp>
20 #include <boost/metaparse/build_parser.hpp>
21
22 #include <boost/mpl/apply_wrap.hpp>
23 #include <boost/mpl/front.hpp>
24 #include <boost/mpl/back.hpp>
25 #include <boost/mpl/plus.hpp>
26 #include <boost/mpl/minus.hpp>
27 #include <boost/mpl/times.hpp>
28 #include <boost/mpl/divides.hpp>
29 #include <boost/mpl/bool.hpp>
30 #include <boost/mpl/equal_to.hpp>
31 #include <boost/mpl/if.hpp>
32
33 using boost::metaparse::sequence;
34 using boost::metaparse::lit_c;
35 using boost::metaparse::last_of;
36 using boost::metaparse::space;
37 using boost::metaparse::repeated;
38 using boost::metaparse::build_parser;
39 using boost::metaparse::int_;
40 using boost::metaparse::foldl_reject_incomplete_start_with_parser;
41 using boost::metaparse::get_result;
42 using boost::metaparse::one_of;
43 using boost::metaparse::token;
44 using boost::metaparse::entire_input;
45 using boost::metaparse::transform;
46 using boost::metaparse::always;
47
48 using boost::mpl::apply_wrap1;
49 using boost::mpl::front;
50 using boost::mpl::back;
51 using boost::mpl::plus;
52 using boost::mpl::minus;
53 using boost::mpl::times;
54 using boost::mpl::divides;
55 using boost::mpl::if_;
56 using boost::mpl::bool_;
57 using boost::mpl::equal_to;
58
59 /*
60 * The grammar
61 *
62 * expression ::= plus_exp
63 * plus_exp ::= prod_exp ((plus_token | minus_token) prod_exp)*
64 * prod_exp ::= value_exp ((mult_token | div_token) value_exp)*
65 * value_exp ::= int_token | '_'
66 */
67
68 typedef token<lit_c<'+'> > plus_token;
69 typedef token<lit_c<'-'> > minus_token;
70 typedef token<lit_c<'*'> > mult_token;
71 typedef token<lit_c<'/'> > div_token;
72
73 typedef token<int_> int_token;
74 typedef token<lit_c<'_'> > arg_token;
75
76 template <class T, char C>
77 struct is_c : bool_<T::type::value == C> {};
78
79 struct build_plus
80 {
81 template <class A, class B>
82 struct _plus
83 {
84 typedef _plus type;
85
86 template <class T>
87 struct apply :
88 plus<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type>
89 {};
90 };
91
92 template <class A, class B>
93 struct _minus
94 {
95 typedef _minus type;
96
97 template <class T>
98 struct apply :
99 minus<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type>
100 {};
101 };
102
103 template <class State, class C>
104 struct apply :
105 if_<
106 typename is_c<front<C>, '+'>::type,
107 _plus<State, typename back<C>::type>,
108 _minus<State, typename back<C>::type>
109 >
110 {};
111 };
112
113 struct build_mult
114 {
115 template <class A, class B>
116 struct _mult
117 {
118 typedef _mult type;
119
120 template <class T>
121 struct apply :
122 times<typename apply_wrap1<A, T>::type, typename apply_wrap1<B, T>::type>
123 {};
124 };
125
126 template <class A, class B>
127 struct _div
128 {
129 typedef _div type;
130
131 template <class T>
132 struct apply :
133 divides<
134 typename apply_wrap1<A, T>::type,
135 typename apply_wrap1<B, T>::type
136 >
137 {};
138 };
139
140 template <class State, class C>
141 struct apply :
142 if_<
143 typename is_c<front<C>, '*'>::type,
144 _mult<State, typename back<C>::type>,
145 _div<State, typename back<C>::type>
146 >
147 {};
148 };
149
150 class build_value
151 {
152 private:
153 template <class V>
154 struct impl
155 {
156 typedef impl type;
157
158 template <class T>
159 struct apply : V {};
160 };
161
162 public:
163 typedef build_value type;
164
165 template <class V>
166 struct apply : impl<typename V::type> {};
167 };
168
169 struct arg
170 {
171 typedef arg type;
172
173 template <class T>
174 struct apply
175 {
176 typedef T type;
177 };
178 };
179
180 typedef
181 one_of<transform<int_token, build_value>, always<arg_token, arg> >
182 value_exp;
183
184 typedef
185 foldl_reject_incomplete_start_with_parser<
186 sequence<one_of<mult_token, div_token>, value_exp>,
187 value_exp,
188 build_mult
189 >
190 prod_exp;
191
192 typedef
193 foldl_reject_incomplete_start_with_parser<
194 sequence<one_of<plus_token, minus_token>, prod_exp>,
195 prod_exp,
196 build_plus
197 >
198 plus_exp;
199
200 typedef last_of<repeated<space>, plus_exp> expression;
201
202 typedef build_parser<entire_input<expression> > metafunction_parser;
203
204 #if BOOST_METAPARSE_STD < 2011
205
206 template <class Exp>
207 struct meta_lambda : apply_wrap1<metafunction_parser, Exp> {};
208
209 int main()
210 {
211 using std::cout;
212 using std::endl;
213 using boost::metaparse::string;
214
215 typedef meta_lambda<string<'1','3'> >::type metafunction_class_1;
216 typedef meta_lambda<string<'2',' ','+',' ','3'> >::type metafunction_class_2;
217 typedef meta_lambda<string<'2',' ','*',' ','2'> >::type metafunction_class_3;
218 typedef
219 meta_lambda<string<' ','1','+',' ','2','*','4','-','6','/','2'> >::type
220 metafunction_class_4;
221 typedef meta_lambda<string<'2',' ','*',' ','_'> >::type metafunction_class_5;
222
223 typedef boost::mpl::int_<11> int11;
224
225 cout
226 << apply_wrap1<metafunction_class_1, int11>::type::value << endl
227 << apply_wrap1<metafunction_class_2, int11>::type::value << endl
228 << apply_wrap1<metafunction_class_3, int11>::type::value << endl
229 << apply_wrap1<metafunction_class_4, int11>::type::value << endl
230 << apply_wrap1<metafunction_class_5, int11>::type::value << endl
231 ;
232 }
233
234 #else
235
236 #ifdef META_LAMBDA
237 #error META_LAMBDA already defined
238 #endif
239 #define META_LAMBDA(exp) \
240 apply_wrap1<metafunction_parser, BOOST_METAPARSE_STRING(#exp)>::type
241
242 int main()
243 {
244 using std::cout;
245 using std::endl;
246
247 typedef META_LAMBDA(13) metafunction_class_1;
248 typedef META_LAMBDA(2 + 3) metafunction_class_2;
249 typedef META_LAMBDA(2 * 2) metafunction_class_3;
250 typedef META_LAMBDA( 1+ 2*4-6/2) metafunction_class_4;
251 typedef META_LAMBDA(2 * _) metafunction_class_5;
252
253 typedef boost::mpl::int_<11> int11;
254
255 cout
256 << apply_wrap1<metafunction_class_1, int11>::type::value << endl
257 << apply_wrap1<metafunction_class_2, int11>::type::value << endl
258 << apply_wrap1<metafunction_class_3, int11>::type::value << endl
259 << apply_wrap1<metafunction_class_4, int11>::type::value << endl
260 << apply_wrap1<metafunction_class_5, int11>::type::value << endl
261 ;
262 }
263
264 #endif
265