1 ///////////////////////////////////////////////////////////////////////////////
4 // Copyright 2008 Eric Niebler. Distributed under the Boost
5 // Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007
9 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007
11 // MS compatible compilers support #pragma once
16 #include <boost/mpl/assert.hpp>
17 #include <boost/type_traits/is_same.hpp>
18 #include <boost/xpressive/detail/detail_fwd.hpp>
19 #include <boost/xpressive/detail/static/static.hpp>
20 #include <boost/proto/core.hpp>
22 namespace boost { namespace xpressive { namespace detail
24 ///////////////////////////////////////////////////////////////////////////////
26 template<uint_t Min, uint_t Max>
27 struct generic_quant_tag
29 typedef mpl::integral_c<uint_t, Min> min_type;
30 typedef mpl::integral_c<uint_t, Max> max_type;
34 namespace boost { namespace xpressive { namespace grammar_detail
38 ///////////////////////////////////////////////////////////////////////////////
39 // min_type / max_type
40 template<typename Tag>
41 struct min_type : Tag::min_type {};
44 struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {};
47 struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {};
50 struct min_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 0> {};
52 template<typename Tag>
53 struct max_type : Tag::max_type {};
56 struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {};
59 struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {};
62 struct max_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 1> {};
64 ///////////////////////////////////////////////////////////////////////////////
65 // as_simple_quantifier
66 template<typename Grammar, typename Greedy, typename Callable = proto::callable>
67 struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> >
69 template<typename Expr, typename State, typename Data>
70 struct impl : proto::transform_impl<Expr, State, Data>
73 typename proto::result_of::child<Expr>::type
77 typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type
81 detail::simple_repeat_matcher<xpr_type, Greedy>
85 typename proto::terminal<matcher_type>::type
88 result_type operator ()(
89 typename impl::expr_param expr
90 , typename impl::state_param
91 , typename impl::data_param data
94 xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()(
96 , detail::true_xpression()
100 typedef typename impl::expr expr_type;
101 matcher_type matcher(
103 , (uint_t)min_type<typename expr_type::proto_tag>::value
104 , (uint_t)max_type<typename expr_type::proto_tag>::value
105 , xpr.get_width().value()
108 return result_type::make(matcher);
113 ///////////////////////////////////////////////////////////////////////////////
115 struct add_hidden_mark : proto::transform<add_hidden_mark>
117 template<typename Expr, typename State, typename Data>
118 struct impl : proto::transform_impl<Expr, State, Data>
120 typedef typename impl::expr expr_type;
122 typename shift_right<
123 terminal<detail::mark_begin_matcher>::type
124 , typename shift_right<
126 , terminal<detail::mark_end_matcher>::type
131 result_type operator ()(
132 typename impl::expr_param expr
133 , typename impl::state_param
134 , typename impl::data_param data
137 // we're inserting a hidden mark ... so grab the next hidden mark number.
138 int mark_nbr = data.get_hidden_mark();
139 detail::mark_begin_matcher begin(mark_nbr);
140 detail::mark_end_matcher end(mark_nbr);
142 result_type that = {{begin}, {expr, {end}}};
148 ///////////////////////////////////////////////////////////////////////////////
152 when<proto::assign<detail::basic_mark_tag, _>, _>
153 , otherwise<add_hidden_mark>
157 ///////////////////////////////////////////////////////////////////////////////
158 // as_default_quantifier_impl
159 template<typename Greedy, uint_t Min, uint_t Max>
160 struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> >
162 template<typename Expr, typename State, typename Data>
163 struct impl : proto::transform_impl<Expr, State, Data>
166 typename proto::result_of::child<Expr>::type
170 typename InsertMark::impl<xpr_type, State, Data>::result_type
174 typename shift_right<
175 terminal<detail::repeat_begin_matcher>::type
176 , typename shift_right<
178 , typename terminal<detail::repeat_end_matcher<Greedy> >::type
183 result_type operator ()(
184 typename impl::expr_param expr
185 , typename impl::state_param state
186 , typename impl::data_param data
189 // Ensure this sub-expression is book-ended with mark matchers
190 marked_sub_type marked_sub =
191 InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data);
193 // Get the mark_number from the begin_mark_matcher
194 int mark_number = proto::value(proto::left(marked_sub)).mark_number_;
195 BOOST_ASSERT(0 != mark_number);
197 typedef typename impl::expr expr_type;
198 uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>();
199 uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>();
201 detail::repeat_begin_matcher begin(mark_number);
202 detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_);
204 result_type that = {{begin}, {marked_sub, {end}}};
210 ///////////////////////////////////////////////////////////////////////////////
212 template<typename Greedy>
216 ///////////////////////////////////////////////////////////////////////////////
217 // as_default_optional
218 template<typename Grammar, typename Greedy, typename Callable = proto::callable>
219 struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> >
221 template<typename Expr, typename State, typename Data>
222 struct impl : proto::transform_impl<Expr, State, Data>
225 detail::alternate_end_xpression
229 detail::optional_matcher<
230 typename Grammar::template impl<Expr, end_xpr, Data>::result_type
235 result_type operator ()(
236 typename impl::expr_param expr
237 , typename impl::state_param
238 , typename impl::data_param data
242 typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
248 ///////////////////////////////////////////////////////////////////////////////
250 template<typename Grammar, typename Greedy, typename Callable = proto::callable>
251 struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> >
253 template<typename Expr, typename State, typename Data>
254 struct impl : proto::transform_impl<Expr, State, Data>
257 detail::alternate_end_xpression
261 detail::optional_mark_matcher<
262 typename Grammar::template impl<Expr, end_xpr, Data>::result_type
267 result_type operator ()(
268 typename impl::expr_param expr
269 , typename impl::state_param
270 , typename impl::data_param data
273 int mark_number = proto::value(proto::left(expr)).mark_number_;
276 typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
283 ///////////////////////////////////////////////////////////////////////////////
284 // IsMarkerOrRepeater
285 struct IsMarkerOrRepeater
287 shift_right<terminal<detail::repeat_begin_matcher>, _>
288 , assign<terminal<detail::mark_placeholder>, _>
292 ///////////////////////////////////////////////////////////////////////////////
294 template<typename Grammar, typename Greedy>
297 when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> >
298 , otherwise<as_default_optional<Grammar, Greedy> >
302 ///////////////////////////////////////////////////////////////////////////////
304 template<typename Greedy, typename Callable = proto::callable>
305 struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> >
307 template<typename Expr, typename State, typename Data>
308 struct impl : proto::transform_impl<Expr, State, Data>
310 typedef typename impl::expr expr_type;
318 result_type operator ()(
319 typename impl::expr_param expr
320 , typename impl::state_param
321 , typename impl::data_param
324 result_type that = {expr};
330 ///////////////////////////////////////////////////////////////////////////////
331 // as_default_quantifier_impl
332 template<typename Greedy, uint_t Max>
333 struct as_default_quantifier_impl<Greedy, 0, Max>
334 : call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)>
337 ///////////////////////////////////////////////////////////////////////////////
338 // as_default_quantifier_impl
339 template<typename Greedy>
340 struct as_default_quantifier_impl<Greedy, 0, 1>
341 : call<make_optional_<Greedy>(_child)>
344 ///////////////////////////////////////////////////////////////////////////////
345 // as_default_quantifier
346 template<typename Greedy, typename Callable = proto::callable>
347 struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> >
349 template<typename Expr, typename State, typename Data>
350 struct impl : proto::transform_impl<Expr, State, Data>
352 typedef typename impl::expr expr_type;
354 as_default_quantifier_impl<
356 , min_type<typename expr_type::proto_tag>::value
357 , max_type<typename expr_type::proto_tag>::value
362 typename other::template impl<Expr, State, Data>::result_type
365 result_type operator ()(
366 typename impl::expr_param expr
367 , typename impl::state_param state
368 , typename impl::data_param data
371 return typename other::template impl<Expr, State, Data>()(expr, state, data);