repeat.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Copyright (c) 2014 Thomas Bernard
  5. Copyright (c) 2017 wanghan02
  6. Copyright (c) 2024 Nana Sakisaka
  7. Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. ==============================================================================*/
  10. #ifndef BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP
  11. #define BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP
  12. #include <boost/spirit/home/x3/core/parser.hpp>
  13. #include <boost/spirit/home/x3/operator/kleene.hpp>
  14. #include <boost/spirit/home/x3/support/expectation.hpp>
  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;
  21. bool got_max(T i) const { return i >= exact_value; }
  22. bool got_min(T i) const { return i >= exact_value; }
  23. T const exact_value;
  24. };
  25. template <typename T>
  26. struct finite_count // handles repeat(min, max)[p]
  27. {
  28. typedef T type;
  29. bool got_max(T i) const { return i >= max_value; }
  30. bool got_min(T i) const { return i >= min_value; }
  31. T const min_value;
  32. T const max_value;
  33. };
  34. template <typename T>
  35. struct infinite_count // handles repeat(min, inf)[p]
  36. {
  37. typedef T type;
  38. bool got_max(T /*i*/) const { return false; }
  39. bool got_min(T i) const { return i >= min_value; }
  40. T const min_value;
  41. };
  42. }}}}
  43. namespace boost { namespace spirit { namespace x3
  44. {
  45. template<typename Subject, typename RepeatCountLimit>
  46. struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>>
  47. {
  48. typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type;
  49. static bool const is_pass_through_unary = true;
  50. static bool const handles_container = true;
  51. constexpr repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
  52. : base_type(subject)
  53. , repeat_limit(repeat_limit_)
  54. {}
  55. template<typename Iterator, typename Context
  56. , typename RContext, typename Attribute>
  57. bool parse(
  58. Iterator& first, Iterator const& last
  59. , Context const& context, RContext& rcontext, Attribute& attr) const
  60. {
  61. Iterator local_iterator = first;
  62. typename RepeatCountLimit::type i{};
  63. for (/**/; !repeat_limit.got_min(i); ++i)
  64. {
  65. if (!detail::parse_into_container(
  66. this->subject, local_iterator, last, context, rcontext, attr))
  67. return false;
  68. }
  69. first = local_iterator;
  70. // parse some more up to the maximum specified
  71. for (/**/; !repeat_limit.got_max(i); ++i)
  72. {
  73. if (!detail::parse_into_container(
  74. this->subject, first, last, context, rcontext, attr))
  75. break;
  76. }
  77. return !has_expectation_failure(context);
  78. }
  79. RepeatCountLimit repeat_limit;
  80. };
  81. // Infinite loop tag type
  82. struct inf_type {};
  83. constexpr inf_type inf = inf_type();
  84. struct repeat_gen
  85. {
  86. template<typename Subject>
  87. constexpr auto operator[](Subject const& subject) const
  88. {
  89. return *as_parser(subject);
  90. }
  91. template <typename T>
  92. struct repeat_gen_lvl1
  93. {
  94. constexpr repeat_gen_lvl1(T&& repeat_limit_)
  95. : repeat_limit(repeat_limit_)
  96. {}
  97. template<typename Subject>
  98. constexpr repeat_directive< typename extension::as_parser<Subject>::value_type, T>
  99. operator[](Subject const& subject) const
  100. {
  101. return { as_parser(subject),repeat_limit };
  102. }
  103. T repeat_limit;
  104. };
  105. template <typename T>
  106. constexpr repeat_gen_lvl1<detail::exact_count<T>>
  107. operator()(T const exact) const
  108. {
  109. return { detail::exact_count<T>{exact} };
  110. }
  111. template <typename T>
  112. constexpr repeat_gen_lvl1<detail::finite_count<T>>
  113. operator()(T const min_val, T const max_val) const
  114. {
  115. return { detail::finite_count<T>{min_val,max_val} };
  116. }
  117. template <typename T>
  118. constexpr repeat_gen_lvl1<detail::infinite_count<T>>
  119. operator()(T const min_val, inf_type const &) const
  120. {
  121. return { detail::infinite_count<T>{min_val} };
  122. }
  123. };
  124. constexpr auto repeat = repeat_gen{};
  125. }}}
  126. namespace boost { namespace spirit { namespace x3 { namespace traits
  127. {
  128. template <typename Subject, typename RepeatCountLimit, typename Context>
  129. struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context>
  130. : build_container<typename attribute_of<Subject, Context>::type> {};
  131. }}}}
  132. #endif