File indexing completed on 2025-12-16 10:09:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP
0012 #define BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP
0013
0014 #include <boost/spirit/home/x3/core/parser.hpp>
0015 #include <boost/spirit/home/x3/operator/kleene.hpp>
0016 #include <boost/spirit/home/x3/support/expectation.hpp>
0017
0018 namespace boost { namespace spirit { namespace x3 { namespace detail
0019 {
0020 template <typename T>
0021 struct exact_count
0022 {
0023 typedef T type;
0024 bool got_max(T i) const { return i >= exact_value; }
0025 bool got_min(T i) const { return i >= exact_value; }
0026
0027 T const exact_value;
0028 };
0029
0030 template <typename T>
0031 struct finite_count
0032 {
0033 typedef T type;
0034 bool got_max(T i) const { return i >= max_value; }
0035 bool got_min(T i) const { return i >= min_value; }
0036
0037 T const min_value;
0038 T const max_value;
0039 };
0040
0041 template <typename T>
0042 struct infinite_count
0043 {
0044 typedef T type;
0045 bool got_max(T ) const { return false; }
0046 bool got_min(T i) const { return i >= min_value; }
0047
0048 T const min_value;
0049 };
0050 }}}}
0051
0052 namespace boost { namespace spirit { namespace x3
0053 {
0054 template<typename Subject, typename RepeatCountLimit>
0055 struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>>
0056 {
0057 typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type;
0058 static bool const is_pass_through_unary = true;
0059 static bool const handles_container = true;
0060
0061 constexpr repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
0062 : base_type(subject)
0063 , repeat_limit(repeat_limit_)
0064 {}
0065
0066 template<typename Iterator, typename Context
0067 , typename RContext, typename Attribute>
0068 bool parse(
0069 Iterator& first, Iterator const& last
0070 , Context const& context, RContext& rcontext, Attribute& attr) const
0071 {
0072 Iterator local_iterator = first;
0073 typename RepeatCountLimit::type i{};
0074 for (; !repeat_limit.got_min(i); ++i)
0075 {
0076 if (!detail::parse_into_container(
0077 this->subject, local_iterator, last, context, rcontext, attr))
0078 return false;
0079 }
0080
0081 first = local_iterator;
0082
0083 for (; !repeat_limit.got_max(i); ++i)
0084 {
0085 if (!detail::parse_into_container(
0086 this->subject, first, last, context, rcontext, attr))
0087 break;
0088 }
0089
0090 return !has_expectation_failure(context);
0091 }
0092
0093 RepeatCountLimit repeat_limit;
0094 };
0095
0096
0097 struct inf_type {};
0098 constexpr inf_type inf = inf_type();
0099
0100 struct repeat_gen
0101 {
0102 template<typename Subject>
0103 constexpr auto operator[](Subject const& subject) const
0104 {
0105 return *as_parser(subject);
0106 }
0107
0108 template <typename T>
0109 struct repeat_gen_lvl1
0110 {
0111 constexpr repeat_gen_lvl1(T&& repeat_limit_)
0112 : repeat_limit(repeat_limit_)
0113 {}
0114
0115 template<typename Subject>
0116 constexpr repeat_directive< typename extension::as_parser<Subject>::value_type, T>
0117 operator[](Subject const& subject) const
0118 {
0119 return { as_parser(subject),repeat_limit };
0120 }
0121
0122 T repeat_limit;
0123 };
0124
0125 template <typename T>
0126 constexpr repeat_gen_lvl1<detail::exact_count<T>>
0127 operator()(T const exact) const
0128 {
0129 return { detail::exact_count<T>{exact} };
0130 }
0131
0132 template <typename T>
0133 constexpr repeat_gen_lvl1<detail::finite_count<T>>
0134 operator()(T const min_val, T const max_val) const
0135 {
0136 return { detail::finite_count<T>{min_val,max_val} };
0137 }
0138
0139 template <typename T>
0140 constexpr repeat_gen_lvl1<detail::infinite_count<T>>
0141 operator()(T const min_val, inf_type const &) const
0142 {
0143 return { detail::infinite_count<T>{min_val} };
0144 }
0145 };
0146
0147 constexpr auto repeat = repeat_gen{};
0148 }}}
0149
0150 namespace boost { namespace spirit { namespace x3 { namespace traits
0151 {
0152 template <typename Subject, typename RepeatCountLimit, typename Context>
0153 struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context>
0154 : build_container<typename attribute_of<Subject, Context>::type> {};
0155 }}}}
0156
0157
0158 #endif