24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.12 Split view [range.split]

24.7.12.3 Class template split_­view​::​outer-iterator [range.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 split_view<V, Pattern>::outer-iterator { private: using Parent = maybe-const<Const, split_view>; // exposition only using Base = maybe-const<Const, V>; // exposition only Parent* parent_ = nullptr; // exposition only iterator_t<Base> current_ = iterator_t<Base>(); // exposition only, present only if V models forward_­range public: using iterator_concept = conditional_t<forward_­range<Base>, forward_iterator_tag, input_iterator_tag>; using iterator_category = input_iterator_tag; // [range.split.outer.value], class split_­view​::​outer-iterator​::​value_­type 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 following specifications refer to the notional member current of outer-iterator.
current is equivalent to current_­ if V models forward_­range, and parent_­->current_­ otherwise.
constexpr explicit outer-iterator(Parent& parent) requires (!forward_­range<Base>);
Effects: Initializes parent_­ with addressof(parent).
constexpr outer-iterator(Parent& parent, iterator_t<Base> current) requires forward_­range<Base>;
Effects: Initializes parent_­ with addressof(parent) and current_­ with std​::​move(current).
constexpr outer-iterator(outer-iterator<!Const> i) requires Const && convertible_­to<iterator_t<V>, iterator_t<Base>>;
Effects: Initializes parent_­ with i.parent_­ and current_­ with std​::​move(i.current_­).
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) return *this; const auto [pbegin, pend] = subrange{parent_->pattern_}; if (pbegin == pend) ++current; else { do { auto [b, p] = ranges::mismatch(std::move(current), end, pbegin, pend); current = std::move(b); if (p == pend) { break; // The pattern matched; skip it } } while (++current != end); } return *this;
friend constexpr bool operator==(const outer-iterator& x, const outer-iterator& y) requires forward_­range<Base>;
Effects: Equivalent to: return x.current_­ == y.current_­;
friend constexpr bool operator==(const outer-iterator& x, default_sentinel_t);
Effects: Equivalent to: return x.current == ranges​::​end(x.parent_­->base_­);