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