seek.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*=============================================================================
  2. Copyright (c) 2011 Jamboree
  3. Copyright (c) 2014 Lee Clagett
  4. Copyright (c) 2017 wanghan02
  5. Copyright (c) 2024 Nana Sakisaka
  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(BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM)
  10. #define BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM
  11. #include <boost/spirit/home/x3/core/parser.hpp>
  12. #include <boost/spirit/home/x3/support/expectation.hpp>
  13. namespace boost { namespace spirit { namespace x3
  14. {
  15. template<typename Subject>
  16. struct seek_directive : unary_parser<Subject, seek_directive<Subject>>
  17. {
  18. typedef unary_parser<Subject, seek_directive<Subject>> base_type;
  19. static bool const is_pass_through_unary = true;
  20. static bool const handles_container = Subject::handles_container;
  21. constexpr seek_directive(Subject const& subject) :
  22. base_type(subject) {}
  23. template<typename Iterator, typename Context
  24. , typename RContext, typename Attribute>
  25. bool parse(
  26. Iterator& first, Iterator const& last
  27. , Context const& context, RContext& rcontext, Attribute& attr) const
  28. {
  29. for (Iterator current(first);; ++current)
  30. {
  31. if (this->subject.parse(current, last, context, rcontext, attr))
  32. {
  33. first = current;
  34. return true;
  35. }
  36. #if !BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
  37. if (has_expectation_failure(context))
  38. {
  39. return false;
  40. }
  41. #endif
  42. // fail only after subject fails & no input
  43. if (current == last)
  44. return false;
  45. }
  46. }
  47. };
  48. struct seek_gen
  49. {
  50. template<typename Subject>
  51. constexpr seek_directive<typename extension::as_parser<Subject>::value_type>
  52. operator[](Subject const& subject) const
  53. {
  54. return { as_parser(subject) };
  55. }
  56. };
  57. constexpr auto seek = seek_gen{};
  58. }}}
  59. #endif