Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:40:35

0001 #ifndef BOOST_PARSER_SPLIT_HPP
0002 #define BOOST_PARSER_SPLIT_HPP
0003 
0004 #include <boost/parser/search.hpp>
0005 
0006 
0007 namespace boost::parser {
0008 
0009     /** Produces a sequence of subranges of the underlying sequence of type
0010         `V`.  the underlying sequence is split into subranges delimited by
0011         matches of the given parser, possibly using a given skip-parser. */
0012     template<
0013 #if BOOST_PARSER_USE_CONCEPTS
0014         std::ranges::viewable_range V,
0015 #else
0016         typename V,
0017 #endif
0018         typename Parser,
0019         typename GlobalState,
0020         typename ErrorHandler,
0021         typename SkipParser>
0022     struct split_view
0023         : detail::stl_interfaces::view_interface<
0024               split_view<V, Parser, GlobalState, ErrorHandler, SkipParser>>
0025     {
0026         constexpr split_view() = default;
0027         constexpr split_view(
0028             V base,
0029             parser_interface<Parser, GlobalState, ErrorHandler> const & parser,
0030             parser_interface<SkipParser> const & skip,
0031             trace trace_mode = trace::off) :
0032             base_(std::move(base)),
0033             parser_(parser),
0034             skip_(skip),
0035             trace_mode_(trace_mode)
0036         {}
0037         constexpr split_view(
0038             V base,
0039             parser_interface<Parser, GlobalState, ErrorHandler> const & parser,
0040             trace trace_mode = trace::off) :
0041             base_(std::move(base)),
0042             parser_(parser),
0043             skip_(),
0044             trace_mode_(trace_mode)
0045         {}
0046 
0047         constexpr V base() const &
0048 #if BOOST_PARSER_USE_CONCEPTS
0049             requires std::copy_constructible<V>
0050 #endif
0051         {
0052             return base_;
0053         }
0054         constexpr V base() && { return std::move(base_); }
0055 
0056         constexpr auto begin() { return iterator<false>{this}; }
0057         constexpr auto end() { return sentinel<false>{}; }
0058 
0059         constexpr auto begin() const
0060 #if BOOST_PARSER_USE_CONCEPTS
0061             requires std::ranges::range<const V>
0062 #endif
0063         {
0064             return iterator<true>{this};
0065         }
0066         constexpr auto end() const
0067 #if BOOST_PARSER_USE_CONCEPTS
0068             requires std::ranges::range<const V>
0069 #endif
0070         {
0071             return sentinel<true>{};
0072         }
0073 
0074         template<bool Const>
0075         struct sentinel
0076         {};
0077 
0078         template<bool Const>
0079         struct iterator
0080             : detail::stl_interfaces::proxy_iterator_interface<
0081                   iterator<Const>,
0082                   std::forward_iterator_tag,
0083                   BOOST_PARSER_SUBRANGE<
0084                       detail::iterator_t<detail::maybe_const<Const, V>>>>
0085         {
0086             using I = detail::iterator_t<detail::maybe_const<Const, V>>;
0087             using S = detail::sentinel_t<detail::maybe_const<Const, V>>;
0088 
0089             constexpr iterator() = default;
0090             constexpr iterator(
0091                 detail::maybe_const<Const, split_view> * parent) :
0092                 parent_(parent),
0093                 r_(parent_->base_.begin(), parent_->base_.end()),
0094                 curr_(r_.begin(), r_.begin()),
0095                 next_it_(r_.begin()),
0096                 next_follows_match_(false)
0097             {
0098                 ++*this;
0099             }
0100 
0101             constexpr iterator & operator++()
0102             {
0103                 if (next_it_ == r_.end() && next_follows_match_) {
0104                     curr_ = BOOST_PARSER_SUBRANGE(next_it_, next_it_);
0105                     next_follows_match_ = false;
0106                     return *this;
0107                 }
0108                 r_ = BOOST_PARSER_SUBRANGE<I, S>(next_it_, r_.end());
0109                 auto const curr_match = parser::search(
0110                     r_, parent_->parser_, parent_->skip_, parent_->trace_mode_);
0111                 curr_ = BOOST_PARSER_SUBRANGE(next_it_, curr_match.begin());
0112                 next_it_ = curr_match.end();
0113                 next_follows_match_ = !curr_match.empty();
0114                 return *this;
0115             }
0116 
0117             constexpr BOOST_PARSER_SUBRANGE<I> operator*() const
0118             {
0119                 return curr_;
0120             }
0121 
0122             friend constexpr bool operator==(iterator lhs, iterator rhs)
0123             {
0124                 return lhs.r_.begin() == rhs.r_.begin();
0125             }
0126             friend constexpr bool operator==(iterator it, sentinel<Const>)
0127             {
0128                 return it.r_.begin() == it.r_.end();
0129             }
0130 
0131             using base_type = detail::stl_interfaces::proxy_iterator_interface<
0132                 iterator,
0133                 std::forward_iterator_tag,
0134                 BOOST_PARSER_SUBRANGE<I>>;
0135             using base_type::operator++;
0136 
0137         private:
0138             detail::maybe_const<Const, split_view> * parent_;
0139             BOOST_PARSER_SUBRANGE<I, S> r_;
0140             BOOST_PARSER_SUBRANGE<I> curr_;
0141             I next_it_;
0142             bool next_follows_match_;
0143         };
0144 
0145         template<bool Const>
0146         friend struct iterator;
0147 
0148     private:
0149         V base_;
0150         parser_interface<Parser, GlobalState, ErrorHandler> parser_;
0151         parser_interface<SkipParser> skip_;
0152         trace trace_mode_;
0153     };
0154 
0155     // deduction guides
0156     template<
0157         typename V,
0158         typename Parser,
0159         typename GlobalState,
0160         typename ErrorHandler,
0161         typename SkipParser>
0162     split_view(
0163         V &&,
0164         parser_interface<Parser, GlobalState, ErrorHandler>,
0165         parser_interface<SkipParser>,
0166         trace)
0167         -> split_view<
0168             detail::text::detail::all_t<V>,
0169             Parser,
0170             GlobalState,
0171             ErrorHandler,
0172             SkipParser>;
0173 
0174     template<
0175         typename V,
0176         typename Parser,
0177         typename GlobalState,
0178         typename ErrorHandler,
0179         typename SkipParser>
0180     split_view(
0181         V &&,
0182         parser_interface<Parser, GlobalState, ErrorHandler>,
0183         parser_interface<SkipParser>)
0184         -> split_view<
0185             detail::text::detail::all_t<V>,
0186             Parser,
0187             GlobalState,
0188             ErrorHandler,
0189             SkipParser>;
0190 
0191     template<
0192         typename V,
0193         typename Parser,
0194         typename GlobalState,
0195         typename ErrorHandler>
0196     split_view(
0197         V &&, parser_interface<Parser, GlobalState, ErrorHandler>, trace)
0198         -> split_view<
0199             detail::text::detail::all_t<V>,
0200             Parser,
0201             GlobalState,
0202             ErrorHandler,
0203             parser_interface<eps_parser<detail::phony>>>;
0204 
0205     template<
0206         typename V,
0207         typename Parser,
0208         typename GlobalState,
0209         typename ErrorHandler>
0210     split_view(V &&, parser_interface<Parser, GlobalState, ErrorHandler>)
0211         -> split_view<
0212             detail::text::detail::all_t<V>,
0213             Parser,
0214             GlobalState,
0215             ErrorHandler,
0216             parser_interface<eps_parser<detail::phony>>>;
0217 
0218     namespace detail {
0219         template<
0220             typename V,
0221             typename Parser,
0222             typename GlobalState,
0223             typename ErrorHandler,
0224             typename SkipParser>
0225         using split_view_expr = decltype(split_view<
0226                                               V,
0227                                               Parser,
0228                                               GlobalState,
0229                                               ErrorHandler,
0230                                               SkipParser>(
0231             std::declval<V>(),
0232             std::declval<
0233                 parser_interface<Parser, GlobalState, ErrorHandler> const &>(),
0234             std::declval<parser_interface<SkipParser> const &>(),
0235             trace::on));
0236 
0237         template<
0238             typename V,
0239             typename Parser,
0240             typename GlobalState,
0241             typename ErrorHandler,
0242             typename SkipParser>
0243         constexpr bool can_split_view = is_detected_v<
0244             split_view_expr,
0245             V,
0246             Parser,
0247             GlobalState,
0248             ErrorHandler,
0249             SkipParser>;
0250 
0251         struct split_impl
0252         {
0253 #if BOOST_PARSER_USE_CONCEPTS
0254 
0255             template<
0256                 parsable_range R,
0257                 typename Parser,
0258                 typename GlobalState,
0259                 typename ErrorHandler,
0260                 typename SkipParser>
0261                 requires(std::ranges::viewable_range<R>) && can_split_view<
0262                                                                 to_range_t<R>,
0263                                                                 Parser,
0264                                                                 GlobalState,
0265                                                                 ErrorHandler,
0266                                                                 SkipParser>
0267             [[nodiscard]] constexpr auto operator()(
0268                 R && r,
0269                 parser_interface<Parser, GlobalState, ErrorHandler> const &
0270                     parser,
0271                 parser_interface<SkipParser> const & skip,
0272                 trace trace_mode = trace::off) const
0273             {
0274                 return split_view(
0275                     to_range<R>::call((R &&)r), parser, skip, trace_mode);
0276             }
0277 
0278             template<
0279                 parsable_range R,
0280                 typename Parser,
0281                 typename GlobalState,
0282                 typename ErrorHandler>
0283                 requires(std::ranges::viewable_range<R>) &&
0284                         can_split_view<
0285                             to_range_t<R>,
0286                             Parser,
0287                             GlobalState,
0288                             ErrorHandler,
0289                             parser_interface<eps_parser<detail::phony>>>
0290             [[nodiscard]] constexpr auto operator()(
0291                 R && r,
0292                 parser_interface<Parser, GlobalState, ErrorHandler> const &
0293                     parser,
0294                 trace trace_mode = trace::off) const
0295             {
0296                 return (*this)(
0297                     (R &&)r,
0298                     parser,
0299                     parser_interface<eps_parser<detail::phony>>{},
0300                     trace_mode);
0301             }
0302 
0303 #else
0304 
0305             template<
0306                 typename R,
0307                 typename Parser,
0308                 typename GlobalState,
0309                 typename ErrorHandler,
0310                 typename SkipParser =
0311                     parser_interface<eps_parser<detail::phony>>,
0312                 typename Trace = trace,
0313                 typename Enable = std::enable_if_t<is_parsable_range_v<R>>>
0314             [[nodiscard]] constexpr auto operator()(
0315                 R && r,
0316                 parser_interface<Parser, GlobalState, ErrorHandler> const &
0317                     parser,
0318                 SkipParser const & skip = SkipParser{},
0319                 Trace trace_mode = Trace{}) const
0320             {
0321                 if constexpr (
0322                     std::
0323                         is_same_v<detail::remove_cv_ref_t<SkipParser>, trace> &&
0324                     std::is_same_v<Trace, trace>) {
0325                     // (r, parser, trace) case
0326                     return impl(
0327                         (R &&) r,
0328                         parser,
0329                         parser_interface<eps_parser<detail::phony>>{},
0330                         skip);
0331                 } else if constexpr (
0332                     detail::is_parser_iface<SkipParser> &&
0333                     std::is_same_v<Trace, trace>) {
0334                     // (r, parser, skip, trace) case
0335                     return impl((R &&) r, parser, skip, trace_mode);
0336                 } else {
0337                     static_assert(
0338                         sizeof(R) == 1 && false,
0339                         "Only the signatures split(R, parser, skip, trace "
0340                         "= trace::off) and split(R, parser, trace = "
0341                         "trace::off) are supported.");
0342                 }
0343             }
0344 
0345         private:
0346             template<
0347                 typename R,
0348                 typename Parser,
0349                 typename GlobalState,
0350                 typename ErrorHandler,
0351                 typename SkipParser>
0352             [[nodiscard]] constexpr auto impl(
0353                 R && r,
0354                 parser_interface<Parser, GlobalState, ErrorHandler> const &
0355                     parser,
0356                 parser_interface<SkipParser> const & skip,
0357                 trace trace_mode = trace::off) const
0358             {
0359                 return split_view(
0360                     to_range<R>::call((R &&) r), parser, skip, trace_mode);
0361             }
0362 
0363 #endif
0364         };
0365     }
0366 
0367     /** A range adaptor object ([range.adaptor.object]).  Given subexpressions
0368         `E` and `P`, `Q`, and `R`, each of the expressions `split(E, P)`,
0369         `split(E, P, Q)`, and `split(E, P, Q, R)` are
0370         expression-equivalent to `split_view(E, P)`, `split_view(E,
0371         P, Q)`, and `split_view(E, P, Q, R)`, respectively. */
0372     inline constexpr detail::stl_interfaces::adaptor<detail::split_impl>
0373         split = detail::split_impl{};
0374 
0375 }
0376 
0377 #if BOOST_PARSER_USE_CONCEPTS
0378 template<
0379     typename V,
0380     typename Parser,
0381     typename GlobalState,
0382     typename ErrorHandler,
0383     typename SkipParser>
0384 constexpr bool std::ranges::enable_borrowed_range<
0385     boost::parser::
0386         split_view<V, Parser, GlobalState, ErrorHandler, SkipParser>> =
0387     std::ranges::enable_borrowed_range<V>;
0388 #endif
0389 
0390 #endif