std::ranges::lazy_split_view<V, Pattern>::outer_iterator

template< bool Const >
struct /*outer_iterator*/;
(1) (since C++20)

The return type of lazy_split_view::begin, and of lazy_split_view::end when the underlying view is a common_range and forward_range.

If either V or Pattern is not a simple view (e.g. if ranges::iterator_t<const V> is invalid or different from ranges::iterator_t<V>), Const is true for iterators returned from the const overloads, and false otherwise. If V is a simple view, Const is true if and only if V is a forward_range.

The name of this class template (shown here as /*outer_iterator*/) is unspecified.

Member types

Member type Definition
Parent (private) const ranges::lazy_split_view if Const is true, otherwise ranges::lazy_split_view. The name is for exposition only.
Base (private) const V if Const is true, otherwise V. The name is for exposition only.
iterator_concept std::forward_iterator_tag if Base models forward_range, otherwise std::forward_iterator_tag.
iterator_category std::input_iterator_tag if Base models forward_range. Not present otherwise.
value_type ranges::lazy_iterator_view<V, Pattern>::/*outer_iterator*/<Const>::value_type.
difference_type ranges::range_difference_t<Base>.

Data members

Typical implementations of outer_iterator hold two or three non-static data members:

  • A pointer of type Parent* to the parent lazy_split_view object (shown here as parent_ for exposition only).
  • An iterator of type ranges::iterator_t<Base> (shown here as current_ for exposition only) into the underlying view; present only if V models forward_range.
  • A boolean flag (shown here as trailing_empty_ for exposition only) that indicates whether an empty trailing subrange (if any) was reached.

Member functions

constructs an iterator
(public member function)
returns the current subrange
(public member function)
advances the iterator
(public member function)
returns conditionally a reference to the current_ (if present) or to the *parent_->current_
(exposition-only member function)

Member functions


/*outer_iterator*/() = default;
(1) (since C++20)
constexpr explicit /*outer_iterator*/( Parent& parent )
  requires (!ranges::forward_range<Base>);
(2) (since C++20)
constexpr /*outer_iterator*/( Parent& parent, ranges::iterator_t<Base> current )
  requires ranges::forward_range<Base>;
(3) (since C++20)
constexpr /*outer_iterator*/( /*outer_iterator*/<!Const> i )
  requires Const && std::convertible_to<ranges::iterator_t<V>,
(4) (since C++20)
1) Value initializes the exposition-only non-static data members with their default member initializer, that is:
  • parent_ = nullptr;,
  • current_ = iterator_t<Base>(); (present only if V models forward_range),
2) Initializes parent_ with std::addressof(parent).
3) Initializes parent_ with std::addressof(parent) and current_ with std::move(current).
4) Initializes parent_ with i.parent_ and current_ with std::move(i.current_).

The exposition-only non-static data member trailing_empty_ is initialized with its default member initializer to false.


constexpr value_type operator*() const;
(since C++20)

Equivalent to return value_type{*this};.


constexpr /*outer_iterator*/& operator++();
(1) (since C++20)
constexpr decltype(auto) operator++(int);
(2) (since C++20)
1) The function body is equivalent to
const auto end = ranges::end(parent_->base_);
  if (/*cur*/() == end) {
    trailing_empty_ = false;
    return *this;
  const auto [pbegin, pend] = ranges::subrange{parent_->pattern_};
  if (pbegin == pend) ++/*cur*/();
  else if constexpr (/*tiny_range*/<Pattern>) {
    /*cur*/() = ranges::find(std::move(/*cur*/()), end, *pbegin);
    if (/*cur*/() != end) {
      if (/*cur*/() == end)
        trailing_empty_ = true;
  else {
    do {
      auto [b, p] = ranges::mismatch(/*cur*/(), end, pbegin, pend);
      if (p == pend) {
        /*cur*/() = b;
        if (/*cur*/() == end)
          trailing_empty_ = true;
        break;            // The pattern matched; skip it
    } while (++/*cur*/() != end);
  return *this;
2) Equivalent to
if constexpr (ranges::forward_range<Base>) {
  auto tmp = *this;
  return tmp;
} else {
  ++*this; // no return statement


constexpr auto& /*cur*/() noexcept;          // exposition only
(1) (since C++20)
constexpr auto& /*cur*/() const noexcept;    // exposition only
(2) (since C++20)

This exposition-only convenience member function is referred to from /*outer_iterator*/::operator++(), from the non-member operator==(const /*outer_iterator*/&, std::default_sentinel_t), and from some member functions of the possible implementation of inner_iterator.

1,2) Equivalent to
if constexpr (ranges::forward_range<V>)

return current_;
return *parent->current_;

Non-member functions

compares the underlying iterators or the underlying iterator and std::default_sentinel


friend constexpr bool operator==( const /*outer_iterator*/& x,
                                  const /*outer_iterator*/& y )
      requires forward_range<Base>;
(1) (since C++20)
friend constexpr bool operator==( const /*outer_iterator*/& x,
                                  std::default_sentinel_t );
(2) (since C++20)
1) Equivalent to return x.current_ == y.current_ and x.trailing_empty_ == y.trailing_empty_;.
2) Equivalent to return x./*cur*/() == ranges::end(x.parent_->base_) and !x.trailing_empty_;.

The != operator is synthesized from operator==.

These functions are not visible to ordinary unqualified or qualified lookup, and can only be found by argument-dependent lookup when std::ranges::split_view::outer_iterator is an associated class of the arguments.

Nested classes

the value type of the outer_iterator
(public member class)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.