confix.hpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*=============================================================================
  2. Copyright (c) 2009 Chris Hoeppler
  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_CONFIX_MAY_30_2014_1819PM)
  10. #define BOOST_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM
  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 Prefix, typename Subject, typename Postfix>
  16. struct confix_directive :
  17. unary_parser<Subject, confix_directive<Prefix, Subject, Postfix>>
  18. {
  19. typedef unary_parser<
  20. Subject, confix_directive<Prefix, Subject, Postfix>> base_type;
  21. static bool const is_pass_through_unary = true;
  22. static bool const handles_container = Subject::handles_container;
  23. constexpr confix_directive(Prefix const& prefix
  24. , Subject const& subject
  25. , Postfix const& postfix) :
  26. base_type(subject),
  27. prefix(prefix),
  28. postfix(postfix)
  29. {
  30. }
  31. template<typename Iterator, typename Context
  32. , typename RContext, typename Attribute>
  33. bool parse(
  34. Iterator& first, Iterator const& last
  35. , Context const& context, RContext& rcontext, Attribute& attr) const
  36. {
  37. Iterator save = first;
  38. if (!(prefix.parse(first, last, context, rcontext, unused) &&
  39. this->subject.parse(first, last, context, rcontext, attr) &&
  40. postfix.parse(first, last, context, rcontext, unused)))
  41. {
  42. #if !BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
  43. if (has_expectation_failure(context))
  44. {
  45. // don't rollback iterator (mimicking exception-like behavior)
  46. return false;
  47. }
  48. #endif
  49. first = save;
  50. return false;
  51. }
  52. return true;
  53. }
  54. Prefix prefix;
  55. Postfix postfix;
  56. };
  57. template<typename Prefix, typename Postfix>
  58. struct confix_gen
  59. {
  60. template<typename Subject>
  61. constexpr confix_directive<
  62. Prefix, typename extension::as_parser<Subject>::value_type, Postfix>
  63. operator[](Subject const& subject) const
  64. {
  65. return { prefix, as_parser(subject), postfix };
  66. }
  67. Prefix prefix;
  68. Postfix postfix;
  69. };
  70. template<typename Prefix, typename Postfix>
  71. constexpr confix_gen<typename extension::as_parser<Prefix>::value_type,
  72. typename extension::as_parser<Postfix>::value_type>
  73. confix(Prefix const& prefix, Postfix const& postfix)
  74. {
  75. return { as_parser(prefix), as_parser(postfix) };
  76. }
  77. }}}
  78. #endif