]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/metaparse/example/constexpr_parser/main.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / metaparse / example / constexpr_parser / main.cpp
CommitLineData
7c673cae
FG
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/sequence.hpp>
7#include <boost/metaparse/lit_c.hpp>
8#include <boost/metaparse/foldl.hpp>
9#include <boost/metaparse/entire_input.hpp>
10#include <boost/metaparse/string.hpp>
11#include <boost/metaparse/build_parser.hpp>
12#include <boost/metaparse/get_result.hpp>
13#include <boost/metaparse/start.hpp>
14#include <boost/metaparse/last_of.hpp>
15#include <boost/metaparse/iterate_c.hpp>
16#include <boost/metaparse/one_char.hpp>
17#include <boost/metaparse/return_.hpp>
18
19#include <boost/mpl/apply_wrap.hpp>
20#include <boost/mpl/at.hpp>
21#include <boost/mpl/int.hpp>
22#include <boost/mpl/plus.hpp>
23#include <boost/mpl/front.hpp>
24#include <boost/mpl/pop_front.hpp>
25#include <boost/mpl/size.hpp>
26
27#include <iostream>
28#include <string>
29
b32b8144 30#if BOOST_METAPARSE_STD < 2011
7c673cae
FG
31
32int main()
33{
34 std::cout
35 << "This example focuses on constexpr, which is not supported"
36 << std::endl;
37}
38
39#else
40
41using boost::metaparse::sequence;
42using boost::metaparse::lit_c;
43using boost::metaparse::build_parser;
44using boost::metaparse::foldl;
45using boost::metaparse::entire_input;
46using boost::metaparse::get_result;
47using boost::metaparse::start;
48using boost::metaparse::last_of;
49using boost::metaparse::iterate_c;
50using boost::metaparse::one_char;
51using boost::metaparse::return_;
52
53using boost::mpl::apply_wrap1;
54using boost::mpl::apply_wrap2;
55using boost::mpl::plus;
56using boost::mpl::int_;
57using boost::mpl::at_c;
58using boost::mpl::front;
59using boost::mpl::pop_front;
60using boost::mpl::size;
61
62using std::ostream;
63
64/*
65 * The grammar
66 *
67 * S ::= a* b* a*
68 */
69
70struct parsed
71{
72 template <class T>
73 constexpr static parsed build()
74 {
75 return
76 parsed(
77 at_c<typename T::type, 0>::type::value,
78 at_c<typename T::type, 1>::type::value,
79 at_c<typename T::type, 2>::type::value
80 );
81 }
82
83 constexpr parsed(int a1, int b, int a2) :
84 a_count1(a1),
85 b_count(b),
86 a_count2(a2)
87 {};
88
89 int a_count1;
90 int b_count;
91 int a_count2;
92};
93
94ostream& operator<<(ostream& o, const parsed& p)
95{
96 return
97 o << "(" << p.a_count1 << ", " << p.b_count << ", " << p.a_count2 << ")";
98}
99
100// constexpr parser
101
102template <class T, int Len>
103struct const_list
104{
105 T head;
106 const_list<T, Len - 1> tail;
107
108 constexpr const_list(const T& h, const const_list<T, Len - 1>& t) :
109 head(h),
110 tail(t)
111 {}
112
113 constexpr const_list<T, Len + 1> push_front(const T& t) const
114 {
115 return const_list<T, Len + 1>(t, *this);
116 }
117
118 constexpr T at(int n) const
119 {
120 return n == 0 ? head : tail.at(n - 1);
121 }
122};
123
124template <class T>
125struct const_list<T, 0>
126{
127 constexpr const_list<T, 1> push_front(const T& t) const
128 {
129 return const_list<T, 1>(t, *this);
130 }
131
132 constexpr T at(int) const
133 {
134 return T();
135 }
136};
137
138template <class T, int N, int from = 0>
139struct to_list
140{
141 static constexpr const_list<T, N - from> run(const T (&s)[N])
142 {
143 return const_list<T, N - from>(s[from], to_list<T, N, from + 1>::run(s));
144 }
145};
146
147template <class T, int N>
148struct to_list<T, N, N>
149{
150 static constexpr const_list<T, 0> run(const T (&s)[N])
151 {
152 return const_list<T, 0>();
153 }
154};
155
156struct presult
157{
158 int value;
159 int remaining_from;
160
161 constexpr presult(int v, int r) : value(v), remaining_from(r) {}
162
163 constexpr presult incr() const { return presult(value + 1, remaining_from); }
164};
165
166template <char C, int N>
167constexpr presult parse_cs(const const_list<char, N>& s, int from)
168{
169 return
170 from < N ?
171 (s.at(from) == C ? parse_cs<C, N>(s, from + 1).incr() : presult(0, from)) :
172 presult(0, from);
173}
174
175template <int N>
176constexpr parsed parse_impl(const const_list<char, N>& s)
177{
178 return
179 parsed(
180 parse_cs<'a', N>(s, 0).value,
181 parse_cs<'b', N>(s, parse_cs<'a', N>(s, 0).remaining_from).value,
182 parse_cs<'a', N>(
183 s,
184 parse_cs<'b', N>(
185 s,
186 parse_cs<'a', N>(s, 0).remaining_from
187 ).remaining_from
188 ).value
189 );
190}
191
192template <int N>
193constexpr parsed parse(const char (&s)[N])
194{
195 return parse_impl(to_list<char, N>::run(s));
196}
197
198// TMP parser
199
200struct count
201{
202 typedef count type;
203
204 template <class State, class C>
205 struct apply : plus<int_<1>, State> {};
206};
207
208typedef foldl<lit_c<'a'>, int_<0>, count> as;
209typedef foldl<lit_c<'b'>, int_<0>, count> bs;
210
211typedef sequence<as, bs, as> s;
212
213typedef build_parser<entire_input<s> > parser;
214
215#ifdef P
216 #error P already defined
217#endif
218#define P(x) \
219 parsed::build<boost::mpl::apply_wrap1<parser, BOOST_METAPARSE_STRING(#x)> >()
220
221// Mixed parser
222
223template <class ValueType, class L, int Len>
224struct tmp_to_const_list_impl
225{
226 constexpr static const_list<ValueType, Len> run()
227 {
228 return
229 const_list<ValueType, Len>(
230 front<L>::type::value,
231 tmp_to_const_list_impl<
232 ValueType,
233 typename pop_front<L>::type,
234 Len - 1
235 >::run()
236 );
237 }
238};
239
240template <class ValueType, class L>
241struct tmp_to_const_list_impl<ValueType, L, 0>
242{
243 constexpr static const_list<ValueType, 0> run()
244 {
245 return const_list<ValueType, 0>();
246 }
247};
248
249template <class ValueType, class L>
250struct tmp_to_const_list :
251 tmp_to_const_list_impl<ValueType, L, size<L>::type::value>
252{};
253
254template <char C>
255struct parse_with_constexpr
256{
257 typedef parse_with_constexpr type;
258
259 template <class S>
260 static constexpr presult impl()
261 {
262 return
263 parse_cs<C, size<S>::type::value>(tmp_to_const_list<char, S>::run(), 0);
264 }
265
266 template <class S, class Pos>
267 struct apply :
268 apply_wrap2<
269 last_of<
270 iterate_c<one_char, impl<S>().remaining_from>,
271 return_<int_<impl<S>().value> >
272 >,
273 S,
274 Pos
275 >
276 {};
277};
278
279typedef parse_with_constexpr<'b'> bs_mixed;
280
281typedef sequence<as, bs_mixed, as> s_mixed;
282
283typedef build_parser<entire_input<s_mixed> > parser_mixed;
284
285#ifdef P_MIXED
286 #error P_MIXED already defined
287#endif
288#define P_MIXED(x) \
289 parsed::build< \
290 boost::mpl::apply_wrap1<parser_mixed, BOOST_METAPARSE_STRING(#x)> \
291 >()
292
293int main()
294{
295 using std::cout;
296 using std::endl;
297
298 cout
299 << "TMP only parsers:" << endl
7c673cae
FG
300 << P(aba) << endl
301 << P(aaaaaaabbbbaaaa) << endl
302 << endl
303
304 << "constexpr only parsers:" << endl
305 << parse("") << endl
306 << parse("aba") << endl
307 << parse("aaaaaaabbbbaaaa") << endl
308 << endl
309
310 << "mixed parsers:" << endl
7c673cae
FG
311 << P_MIXED(aba) << endl
312 << P_MIXED(aaaaaaabbbbaaaa) << endl
313 << endl
314 ;
315}
316
317#endif
318