1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 Copyright (c) 2001-2011 Hartmut Kaiser 4 Copyright (c) 2014 Thomas Bernard 5 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 #ifndef BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP 10 #define BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP 11 12 #include <boost/spirit/home/x3/core/parser.hpp> 13 #include <boost/spirit/home/x3/operator/kleene.hpp> 14 15 namespace boost { namespace spirit { namespace x3 { namespace detail 16 { 17 template <typename T> 18 struct exact_count // handles repeat(exact)[p] 19 { 20 typedef T type; got_maxboost::spirit::x3::detail::exact_count21 bool got_max(T i) const { return i >= exact_value; } got_minboost::spirit::x3::detail::exact_count22 bool got_min(T i) const { return i >= exact_value; } 23 24 T const exact_value; 25 }; 26 27 template <typename T> 28 struct finite_count // handles repeat(min, max)[p] 29 { 30 typedef T type; got_maxboost::spirit::x3::detail::finite_count31 bool got_max(T i) const { return i >= max_value; } got_minboost::spirit::x3::detail::finite_count32 bool got_min(T i) const { return i >= min_value; } 33 34 T const min_value; 35 T const max_value; 36 }; 37 38 template <typename T> 39 struct infinite_count // handles repeat(min, inf)[p] 40 { 41 typedef T type; got_maxboost::spirit::x3::detail::infinite_count42 bool got_max(T /*i*/) const { return false; } got_minboost::spirit::x3::detail::infinite_count43 bool got_min(T i) const { return i >= min_value; } 44 45 T const min_value; 46 }; 47 }}}} 48 49 namespace boost { namespace spirit { namespace x3 50 { 51 template<typename Subject, typename RepeatCountLimit> 52 struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> 53 { 54 typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type; 55 static bool const is_pass_through_unary = true; 56 static bool const handles_container = true; 57 repeat_directiveboost::spirit::x3::repeat_directive58 constexpr repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_) 59 : base_type(subject) 60 , repeat_limit(repeat_limit_) 61 {} 62 63 template<typename Iterator, typename Context 64 , typename RContext, typename Attribute> parseboost::spirit::x3::repeat_directive65 bool parse( 66 Iterator& first, Iterator const& last 67 , Context const& context, RContext& rcontext, Attribute& attr) const 68 { 69 Iterator local_iterator = first; 70 typename RepeatCountLimit::type i{}; 71 for (/**/; !repeat_limit.got_min(i); ++i) 72 { 73 if (!detail::parse_into_container( 74 this->subject, local_iterator, last, context, rcontext, attr)) 75 return false; 76 } 77 78 first = local_iterator; 79 // parse some more up to the maximum specified 80 for (/**/; !repeat_limit.got_max(i); ++i) 81 { 82 if (!detail::parse_into_container( 83 this->subject, first, last, context, rcontext, attr)) 84 break; 85 } 86 return true; 87 } 88 89 RepeatCountLimit repeat_limit; 90 }; 91 92 // Infinite loop tag type 93 struct inf_type {}; 94 constexpr inf_type inf = inf_type(); 95 96 struct repeat_gen 97 { 98 template<typename Subject> operator []boost::spirit::x3::repeat_gen99 constexpr auto operator[](Subject const& subject) const 100 { 101 return *as_parser(subject); 102 } 103 104 template <typename T> 105 struct repeat_gen_lvl1 106 { repeat_gen_lvl1boost::spirit::x3::repeat_gen::repeat_gen_lvl1107 constexpr repeat_gen_lvl1(T&& repeat_limit_) 108 : repeat_limit(repeat_limit_) 109 {} 110 111 template<typename Subject> 112 constexpr repeat_directive< typename extension::as_parser<Subject>::value_type, T> operator []boost::spirit::x3::repeat_gen::repeat_gen_lvl1113 operator[](Subject const& subject) const 114 { 115 return { as_parser(subject),repeat_limit }; 116 } 117 118 T repeat_limit; 119 }; 120 121 template <typename T> 122 constexpr repeat_gen_lvl1<detail::exact_count<T>> operator ()boost::spirit::x3::repeat_gen123 operator()(T const exact) const 124 { 125 return { detail::exact_count<T>{exact} }; 126 } 127 128 template <typename T> 129 constexpr repeat_gen_lvl1<detail::finite_count<T>> operator ()boost::spirit::x3::repeat_gen130 operator()(T const min_val, T const max_val) const 131 { 132 return { detail::finite_count<T>{min_val,max_val} }; 133 } 134 135 template <typename T> 136 constexpr repeat_gen_lvl1<detail::infinite_count<T>> operator ()boost::spirit::x3::repeat_gen137 operator()(T const min_val, inf_type const &) const 138 { 139 return { detail::infinite_count<T>{min_val} }; 140 } 141 }; 142 143 constexpr auto repeat = repeat_gen{}; 144 }}} 145 146 namespace boost { namespace spirit { namespace x3 { namespace traits 147 { 148 template <typename Subject, typename RepeatCountLimit, typename Context> 149 struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context> 150 : build_container<typename attribute_of<Subject, Context>::type> {}; 151 }}}} 152 153 154 #endif 155