23 Ranges library [ranges]

23.8 Range adaptors [range.adaptors]

23.8.8 Split view [range.split]

23.8.8.5 Class template split_­view​::​inner_­iterator [range.split.inner]

namespace std::ranges {
  template<class V, class Pattern>
  template<bool Const>
  struct split_view<V, Pattern>::inner_iterator {
  private:
    using Base =
      conditional_t<Const, const V, V>;                 // exposition only
    outer_iterator<Const> i_ = outer_iterator<Const>(); // exposition only
    bool incremented_ = false;                          // exposition only
  public:
    using iterator_concept  = typename outer_iterator<Const>::iterator_concept;
    using iterator_category = see below;
    using value_type        = iter_value_t<iterator_t<Base>>;
    using difference_type   = iter_difference_t<iterator_t<Base>>;

    inner_iterator() = default;
    constexpr explicit inner_iterator(outer_iterator<Const> i);

    constexpr decltype(auto) operator*() const { return *i_.current; }

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

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

    friend constexpr bool operator==(const inner_iterator& x, default_sentinel_t);
    friend constexpr bool operator==(default_sentinel_t, const inner_iterator& x);
    friend constexpr bool operator!=(const inner_iterator& x, default_sentinel_t y);
    friend constexpr bool operator!=(default_sentinel_t y, const inner_iterator& x);

    friend constexpr decltype(auto) iter_move(const inner_iterator& i)
    noexcept(noexcept(ranges::iter_move(i.i_.current))) {
      return ranges::iter_move(i.i_.current);
    }

    friend constexpr void iter_swap(const inner_iterator& x, const inner_iterator& y)
      noexcept(noexcept(ranges::iter_swap(x.i_.current, y.i_.current)))
      requires IndirectlySwappable<iterator_t<Base>>;
  };
}
The typedef-name iterator_­category denotes forward_­iterator_­tag if iterator_­traits<iterator_­t<Base>>::iterator_­category models DerivedFrom<forward_­iterator_­tag>, and input_­iterator_­tag otherwise.
constexpr explicit inner_iterator(outer_iterator<Const> i);
Effects: Initializes i_­ with i.
constexpr inner_iterator& operator++() const;
Effects: Equivalent to:
incremented_ = true;
if constexpr (!ForwardRange<Base>) {
  if constexpr (Pattern::size() == 0) {
    return *this;
  }
}
++i_.current;
return *this;
friend constexpr bool operator==(const inner_iterator& x, const inner_iterator& y) requires ForwardRange<Base>;
Effects: Equivalent to: return x.i_­.current_­ == y.i_­.current_­;
friend constexpr bool operator!=(const inner_iterator& x, const inner_iterator& y) requires ForwardRange<Base>;
Effects: Equivalent to: return !(x == y);
friend constexpr bool operator==(const inner_iterator& x, default_sentinel_t); friend constexpr bool operator==(default_sentinel_t, const inner_iterator& x);
Effects: Equivalent to:
auto cur = x.i_.current;
auto end = ranges::end(x.i_.parent_->base_);
if (cur == end) return true;
auto [pcur, pend] = subrange{x.i_.parent_->pattern_};
if (pcur == pend) return x.incremented_;
do {
  if (*cur != *pcur) return false;
  if (++pcur == pend) return true;
} while (++cur != end);
return false;
friend constexpr bool operator!=(const inner_iterator& x, default_sentinel_t y); friend constexpr bool operator!=(default_sentinel_t y, const inner_iterator& x);
Effects: Equivalent to: return !(x == y);
friend constexpr void iter_swap(const inner_iterator& x, const inner_iterator& y) noexcept(noexcept(ranges::iter_swap(x.i_.current, y.i_.current))) requires IndirectlySwappable<iterator_t<Base>>;
Effects: Equivalent to ranges::iter_­swap(x.i_­.current, y.i_­.current).