24 Ranges library [ranges]

24.7 Range adaptors [range.adaptors]

24.7.8 Split view [range.split]

24.7.8.3 Class template split_­view​::​outer_­iterator [range.split.outer]

namespace std::ranges {
  template<class V, class Pattern>
  template<bool Const>
  struct split_view<V, Pattern>::outer_iterator {
  private:
    using Parent =                              // exposition only
      conditional_t<Const, const split_view, split_view>;
    using Base   =                              // exposition only
      conditional_t<Const, const V, V>;
    Parent* parent_ = nullptr;                  // exposition only
    iterator_t<Base> current_ =                 // exposition only, present only if V models ForwardRange
      iterator_t<Base>();

  public:
    using iterator_concept  =
      conditional_t<ForwardRange<Base>, forward_iterator_tag, input_iterator_tag>;
    using iterator_category = input_iterator_tag;
    struct value_type;                                  // see [range.split.outer.value]
    using difference_type   = iter_difference_t<iterator_t<Base>>;

    outer_iterator() = default;
    constexpr explicit outer_iterator(Parent& parent)
      requires (!ForwardRange<Base>);
    constexpr outer_iterator(Parent& parent, iterator_t<Base> current)
      requires ForwardRange<Base>;
    constexpr outer_iterator(outer_iterator<!Const> i)
      requires Const && ConvertibleTo<iterator_t<V>, iterator_t<const V>>;

    constexpr value_type operator*() const;

    constexpr outer_iterator& operator++();
    constexpr decltype(auto) operator++(int) {
      if constexpr (ForwardRange<Base>) {
        auto tmp = *this;
        ++*this;
        return tmp;
      } else
        ++*this;
    }

    friend constexpr bool operator==(const outer_iterator& x, const outer_iterator& y)
      requires ForwardRange<Base>;
    friend constexpr bool operator!=(const outer_iterator& x, const outer_iterator& y)
      requires ForwardRange<Base>;

    friend constexpr bool operator==(const outer_iterator& x, default_sentinel_t);
    friend constexpr bool operator==(default_sentinel_t, const outer_iterator& x);
    friend constexpr bool operator!=(const outer_iterator& x, default_sentinel_t y);
    friend constexpr bool operator!=(default_sentinel_t y, const outer_iterator& x);
  };
}
Many of the following specifications refer to the notional member current of outer_­iterator.
current is equivalent to current_­ if V models ForwardRange, and parent_­->current_­ otherwise.
constexpr explicit outer_iterator(Parent& parent) requires (!ForwardRange<Base>);
Effects: Initializes parent_­ with addressof(parent).
constexpr outer_iterator(Parent& parent, iterator_t<Base> current) requires ForwardRange<Base>;
Effects: Initializes parent_­ with addressof(parent) and current_­ with current.
constexpr outer_iterator(outer_iterator<!Const> i) requires Const && ConvertibleTo<iterator_t<V>, iterator_t<const V>>;
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 {
    const auto [b, p] = ranges::mismatch(current, end, pbegin, pend);
    if (p == pend) {
      current = b;  // The pattern matched; skip it
      break;
    }
  } while (++current != end);
}
return *this;
friend constexpr bool operator==(const outer_iterator& x, const outer_iterator& y) requires ForwardRange<Base>;
Effects: Equivalent to: return x.current_­ == y.current_­;
friend constexpr bool operator!=(const outer_iterator& x, const outer_iterator& y) requires ForwardRange<Base>;
Effects: Equivalent to: return !(x == y);
friend constexpr bool operator==(const outer_iterator& x, default_sentinel_t); friend constexpr bool operator==(default_sentinel_t, const outer_iterator& x);
Effects: Equivalent to: return x.current == ranges::end(x.parent_­->base_­);
friend constexpr bool operator!=(const outer_iterator& x, default_sentinel_t y); friend constexpr bool operator!=(default_sentinel_t y, const outer_iterator& x);
Effects: Equivalent to: return !(x == y);