File indexing completed on 2025-12-16 10:09:35
0001
0002
0003
0004
0005
0006
0007
0008
0009 #if !defined(BOOST_SPIRIT_X3_SKIP_JANUARY_26_2008_0422PM)
0010 #define BOOST_SPIRIT_X3_SKIP_JANUARY_26_2008_0422PM
0011
0012 #include <boost/spirit/home/x3/support/context.hpp>
0013 #include <boost/spirit/home/x3/support/unused.hpp>
0014 #include <boost/spirit/home/x3/support/expectation.hpp>
0015 #include <boost/spirit/home/x3/core/skip_over.hpp>
0016 #include <boost/spirit/home/x3/core/parser.hpp>
0017 #include <boost/utility/enable_if.hpp>
0018
0019 namespace boost { namespace spirit { namespace x3
0020 {
0021 template <typename Subject>
0022 struct reskip_directive : unary_parser<Subject, reskip_directive<Subject>>
0023 {
0024 typedef unary_parser<Subject, reskip_directive<Subject>> base_type;
0025 static bool const is_pass_through_unary = true;
0026 static bool const handles_container = Subject::handles_container;
0027
0028 constexpr reskip_directive(Subject const& subject)
0029 : base_type(subject) {}
0030
0031 template <typename Iterator, typename Context
0032 , typename RContext, typename Attribute>
0033 typename disable_if<has_skipper<Context>, bool>::type
0034 parse(Iterator& first, Iterator const& last
0035 , Context& context, RContext& rcontext, Attribute& attr) const
0036 {
0037 auto const& skipper =
0038 detail::get_unused_skipper(x3::get<skipper_tag>(context));
0039
0040 auto const local_ctx = make_context<skipper_tag>(skipper, context);
0041 bool const r = this->subject.parse(first, last, local_ctx, rcontext, attr);
0042
0043 #if !BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
0044 if (has_expectation_failure(local_ctx))
0045 {
0046 set_expectation_failure(get_expectation_failure(local_ctx), context);
0047 }
0048 #endif
0049
0050 return r;
0051 }
0052 template <typename Iterator, typename Context
0053 , typename RContext, typename Attribute>
0054 typename enable_if<has_skipper<Context>, bool>::type
0055 parse(Iterator& first, Iterator const& last
0056 , Context const& context, RContext& rcontext, Attribute& attr) const
0057 {
0058 return this->subject.parse(first, last, context, rcontext, attr);
0059 }
0060 };
0061
0062 template <typename Subject, typename Skipper>
0063 struct skip_directive : unary_parser<Subject, skip_directive<Subject, Skipper>>
0064 {
0065 typedef unary_parser<Subject, skip_directive<Subject, Skipper>> base_type;
0066 static bool const is_pass_through_unary = true;
0067 static bool const handles_container = Subject::handles_container;
0068
0069 constexpr skip_directive(Subject const& subject, Skipper const& skipper)
0070 : base_type(subject)
0071 , skipper(skipper)
0072 {}
0073
0074 template <typename Iterator, typename RContext, typename Attribute>
0075 bool parse(Iterator& first, Iterator const& last
0076 , unused_type const&, RContext& rcontext, Attribute& attr) const
0077 {
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 return this->subject.parse(first, last,
0098 make_context<skipper_tag>(skipper), rcontext, attr);
0099 }
0100
0101 template <typename Iterator, typename Context, typename RContext, typename Attribute>
0102 bool parse(Iterator& first, Iterator const& last
0103 , Context const& context, RContext& rcontext, Attribute& attr) const
0104 {
0105 #if BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE
0106 return this->subject.parse(first, last, make_context<skipper_tag>(skipper, context), rcontext, attr);
0107
0108 #else
0109 static_assert(
0110 !std::is_same_v<expectation_failure_t<Context>, unused_type>,
0111 "Context type was not specified for x3::expectation_failure_tag. "
0112 "You probably forgot: `x3::with<x3::expectation_failure_tag>(failure)[p]`. "
0113 "Note that you must also bind the context to your skipper.");
0114
0115
0116
0117 auto const local_ctx = make_context<skipper_tag>(skipper, context);
0118 bool const r = this->subject.parse(first, last, local_ctx, rcontext, attr);
0119
0120 if (has_expectation_failure(local_ctx))
0121 {
0122 set_expectation_failure(get_expectation_failure(local_ctx), context);
0123 }
0124 return r;
0125 #endif
0126 }
0127
0128 Skipper const skipper;
0129 };
0130
0131 struct reskip_gen
0132 {
0133 template <typename Skipper>
0134 struct skip_gen
0135 {
0136 constexpr skip_gen(Skipper const& skipper)
0137 : skipper_(skipper) {}
0138
0139 template <typename Subject>
0140 constexpr skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
0141 operator[](Subject const& subject) const
0142 {
0143 return { as_parser(subject), skipper_ };
0144 }
0145
0146 Skipper skipper_;
0147 };
0148
0149 template <typename Skipper>
0150 constexpr skip_gen<Skipper> const operator()(Skipper const& skipper) const
0151 {
0152 return { skipper };
0153 }
0154
0155 template <typename Subject>
0156 constexpr reskip_directive<typename extension::as_parser<Subject>::value_type>
0157 operator[](Subject const& subject) const
0158 {
0159 return { as_parser(subject) };
0160 }
0161 };
0162
0163 constexpr auto skip = reskip_gen{};
0164 }}}
0165
0166 #endif