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

Ranges library
Range access
Range conversions
Range primitives

Dangling iterator handling
Range concepts


Range adaptor objects
Range adaptor closure objects
Helper items
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.


[edit] 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>.

[edit] 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.

[edit] 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)

[edit] 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_;

[edit] 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.

[edit] Nested classes

the value type of the outer_iterator
(public member class)