File indexing completed on 2025-09-17 08:40:35
0001
0002
0003
0004
0005
0006 #ifndef BOOST_PARSER_SUBRANGE_HPP
0007 #define BOOST_PARSER_SUBRANGE_HPP
0008
0009 #include <boost/parser/detail/text/config.hpp>
0010 #include <boost/parser/detail/text/detail/algorithm.hpp>
0011
0012 #include <boost/parser/detail/stl_interfaces/view_interface.hpp>
0013
0014
0015 namespace boost::parser {
0016
0017
0018
0019 #if BOOST_PARSER_USE_CONCEPTS
0020 template<std::forward_iterator I, std::sentinel_for<I> S = I>
0021 #else
0022 template<typename I, typename S = I>
0023 #endif
0024 struct subrange : detail::stl_interfaces::view_interface<subrange<I, S>>
0025 {
0026 constexpr subrange() = default;
0027 constexpr subrange(I first, S last) : first_(first), last_(last) {}
0028 template<typename R>
0029 constexpr explicit subrange(R const & r) :
0030 first_(detail::text::detail::begin(r)),
0031 last_(detail::text::detail::end(r))
0032 {}
0033
0034 constexpr I begin() const { return first_; }
0035 constexpr S end() const { return last_; }
0036
0037 [[nodiscard]] constexpr subrange next(std::ptrdiff_t n = 1) const
0038 {
0039 return subrange{detail::text::detail::next(first_), last_};
0040 }
0041 [[nodiscard]] constexpr subrange prev(std::ptrdiff_t n = 1) const
0042 {
0043 return subrange{detail::text::detail::prev(first_), last_};
0044 }
0045
0046 constexpr subrange & advance(std::ptrdiff_t n)
0047 {
0048 std::advance(first_, n);
0049 return *this;
0050 }
0051
0052 template<
0053 typename I2,
0054 typename S2,
0055 typename Enable = std::enable_if_t<
0056 std::is_convertible<I, I2>::value &&
0057 std::is_convertible<S, S2>::value>>
0058 constexpr operator subrange<I2, S2>() const
0059 {
0060 return {first_, last_};
0061 }
0062
0063 private:
0064 I first_;
0065 [[no_unique_address]] S last_;
0066 };
0067
0068 #if defined(__cpp_deduction_guides)
0069 #if BOOST_PARSER_USE_CONCEPTS
0070 template<std::input_or_output_iterator I, std::sentinel_for<I> S>
0071 #else
0072 template<typename I, typename S>
0073 #endif
0074 subrange(I, S) -> subrange<I, S>;
0075
0076 #if BOOST_PARSER_USE_CONCEPTS
0077 template<std::ranges::borrowed_range R>
0078 #else
0079 template<typename R>
0080 #endif
0081 subrange(R &&) -> subrange<
0082 detail::text::detail::iterator_t<R>,
0083 detail::text::detail::sentinel_t<R>>;
0084 #endif
0085
0086
0087 #if BOOST_PARSER_USE_CONCEPTS
0088 template<std::forward_iterator I, std::sentinel_for<I> S = I>
0089 #else
0090 template<typename I, typename S = I>
0091 #endif
0092 constexpr subrange<I, S> make_subrange(I first, S last) noexcept
0093 {
0094 return subrange<I, S>(first, last);
0095 }
0096
0097 }
0098
0099 #if BOOST_PARSER_USE_CONCEPTS
0100
0101 namespace std::ranges {
0102 template<std::forward_iterator I, std::sentinel_for<I> S>
0103 inline constexpr bool enable_borrowed_range<boost::parser::subrange<I, S>> =
0104 true;
0105 }
0106
0107 #endif
0108
0109 #endif