[range.lazy.split.outer] (original) (raw)

25 Ranges library [ranges]

25.7 Range adaptors [range.adaptors]

25.7.16 Lazy split view [range.lazy.split]

25.7.16.3 Class template lazy_split_view​::​outer-iterator [range.lazy.split.outer]

namespace std::ranges { template<input_range V, forward_range Pattern> requires view<V> && view<Pattern> && indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> && (forward_range<V> || tiny-range<Pattern>) template<bool Const> struct lazy_split_view<V, Pattern>::outer-iterator { private: using Parent = maybe-const<Const, lazy_split_view>; using Base = maybe-const<Const, V>; Parent* parent_ = nullptr; iterator_t<_Base_> current_ = iterator_t<_Base_>(); bool trailing_empty_ = false; public: using iterator_concept = conditional_t<forward_range<_Base_>, forward_iterator_tag, input_iterator_tag>;using iterator_category = input_iterator_tag; struct value_type;using difference_type = range_difference_t<_Base_>;outer-iterator() = default;constexpr explicit outer-iterator(Parent& parent) requires (forward\_range<_Base_>);constexpr outer-iterator(Parent& parent, iterator_t<_Base_> current) requires forward_range<_Base_>;constexpr outer-iterator(outer-iterator<!Const> i) requires Const && convertible_to<iterator_t<V>, iterator_t<_Base_>>;constexpr value_type operator*() const;constexpr outer-iterator& operator++();constexpr decltype(auto) operator++(int) { if constexpr (forward_range<_Base_>) { auto tmp = *this;++*this;return tmp;} else ++*this;} friend constexpr bool operator==(const outer-iterator& x, const outer-iterator& y) requires forward_range<_Base_>;friend constexpr bool operator==(const outer-iterator& x, default_sentinel_t);};}

Many of the specifications in [range.lazy.split] refer to the notional member_current_ of outer-iterator.

current is equivalent to current_ if Vmodels forward_range, and *_parent__->current_ otherwise.

constexpr explicit _outer-iterator_(_Parent_& parent) requires (![forward_range](range.refinements#concept:forward%5Frange "25.4.5 Other range refinements [range.refinements]")<_Base_>);

Effects: Initializes parent_ with addressof(parent).

constexpr _outer-iterator_(_Parent_& parent, iterator_t<_Base_> current) requires [forward_range](range.refinements#concept:forward%5Frange "25.4.5 Other range refinements [range.refinements]")<_Base_>;

Effects: Initializes parent_ with addressof(parent)and current_ with std​::​move(current).

constexpr _outer-iterator_(_outer-iterator_<!Const> i) requires Const && [convertible_to](concept.convertible#concept:convertible%5Fto "18.4.4 Concept convertible_­to [concept.convertible]")<iterator_t<V>, iterator_t<_Base_>>;

Effects: Initializes parent_ with i.parent_,current_ with std​::​move(i.current_), and_trailing_empty__ with i.trailing_empty_.

constexpr value_type operator*() const;

Effects: Equivalent to: return value_type{*this};

constexpr _outer-iterator_& operator++();

Effects: Equivalent to:const auto end = ranges::end(_parent__->base_);if (current == end) { trailing_empty_ = false;return *this;} const auto [pbegin, pend] = subrange{_parent__->pattern_};if (pbegin == pend) ++current;else if constexpr (tiny-range<Pattern>) { current = ranges::find(std::move(current), end, *pbegin);if (current != end) { ++current;if (current == end) trailing_empty_ = true;} } else { do { auto [b, p] = ranges::mismatch(current, end, pbegin, pend);if (p == pend) { current = b;if (current == end) trailing_empty_ = true;break; } } while (++current != end);} return *this;

friend constexpr bool operator==(const _outer-iterator_& x, const _outer-iterator_& y) requires [forward_range](range.refinements#concept:forward%5Frange "25.4.5 Other range refinements [range.refinements]")<_Base_>;

Effects: Equivalent to:return x.current_ == y.current_ && x.trailing_empty_ == y.trailing_empty_;

friend constexpr bool operator==(const _outer-iterator_& x, default_sentinel_t);

Effects: Equivalent to:return x.current == ranges::end(x._parent__->base_) && !x.trailing_empty_;