Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Copyright (C) 2022 T. Zachary Laine
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
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     /** A simple view type used throughout the rest of the library in C++17
0018         builds; similar to `std::ranges::subrange`. */
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     /** Makes a `subrange<I, S>` from an `I` and an `S`. */
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