1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
4 Copyright (c) 2014 Thomas Bernard
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(SPIRIT_X3_REPEAT_APRIL_16_2014_0848AM)
10 #define SPIRIT_X3_REPEAT_APRIL_16_2014_0848AM
12 #include <boost/function_types/function_type.hpp>
13 #include <boost/function_types/parameter_types.hpp>
14 #include <boost/spirit/home/x3/core/parser.hpp>
15 #include <boost/spirit/home/x3/operator/kleene.hpp>
17 namespace boost { namespace spirit { namespace x3 { namespace detail
20 struct exact_count // handles repeat(exact)[p]
23 bool got_max(T i) const { return i >= exact_value; }
24 bool got_min(T i) const { return i >= exact_value; }
30 struct finite_count // handles repeat(min, max)[p]
33 bool got_max(T i) const { return i >= max_value; }
34 bool got_min(T i) const { return i >= min_value; }
41 struct infinite_count // handles repeat(min, inf)[p]
44 bool got_max(T /*i*/) const { return false; }
45 bool got_min(T i) const { return i >= min_value; }
51 namespace boost { namespace spirit { namespace x3
53 template<typename Subject, typename RepeatCountLimit>
54 struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>>
56 typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type;
57 static bool const is_pass_through_unary = true;
58 static bool const handles_container = true;
60 repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
62 , repeat_limit(repeat_limit_)
65 template<typename Iterator, typename Context
66 , typename RContext, typename Attribute>
68 Iterator& first, Iterator const& last
69 , Context const& context, RContext& rcontext, Attribute& attr) const
71 Iterator local_iterator = first;
72 typename RepeatCountLimit::type i{};
73 for (/**/; !repeat_limit.got_min(i); ++i)
75 if (!detail::parse_into_container(
76 this->subject, local_iterator, last, context, rcontext, attr))
80 first = local_iterator;
81 // parse some more up to the maximum specified
82 for (/**/; !repeat_limit.got_max(i); ++i)
84 if (!detail::parse_into_container(
85 this->subject, first, last, context, rcontext, attr))
91 RepeatCountLimit repeat_limit;
94 // Infinite loop tag type
96 const inf_type inf = inf_type();
100 template<typename Subject>
101 kleene<typename extension::as_parser<Subject>::value_type>
102 operator[](Subject const& subject) const
104 return { as_parser(subject) };
107 template <typename T>
108 struct repeat_gen_lvl1
110 repeat_gen_lvl1(T&& repeat_limit_)
111 : repeat_limit(repeat_limit_)
114 template<typename Subject>
115 repeat_directive< typename extension::as_parser<Subject>::value_type, T>
116 operator[](Subject const& subject) const
118 return { as_parser(subject),repeat_limit };
124 template <typename T>
125 repeat_gen_lvl1<detail::exact_count<T>>
126 operator()(T const exact) const
128 return { detail::exact_count<T>{exact} };
131 template <typename T>
132 repeat_gen_lvl1<detail::finite_count<T>>
133 operator()(T const min_val, T const max_val) const
135 return { detail::finite_count<T>{min_val,max_val} };
138 template <typename T>
139 repeat_gen_lvl1<detail::infinite_count<T>>
140 operator()(T const min_val, inf_type const &) const
142 return { detail::infinite_count<T>{min_val} };
146 auto const repeat = repeat_gen{};
149 namespace boost { namespace spirit { namespace x3 { namespace traits
151 template <typename Subject, typename RepeatCountLimit, typename Context>
152 struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context>
153 : build_container<typename attribute_of<Subject, Context>::type> {};