std::ranges...er_iterator(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::ranges...er_iterator(3) β€” C++ Standard Libary πŸ’…

okay bestie, welcome to std::ranges...er_iterator(3) from the C++ Standard Libary manual. this page is literally all about the exposition-only outer iterator for lazy_split_view, and yes it has lore ✨


🌸 NAME 🌸

std::ranges::lazy_split_view::outer_iterator β€” that's it, that's the name: std::ranges::lazy_split_view::outer_iterator πŸ’–


✨ SYNOPSIS ✨

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

This is 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.


πŸŽ€ MEMBER TYPES πŸŽ€

  • Parent β€” const ranges::lazy_split_view if Const is true, otherwise ranges::lazy_split_view (exposition-only member type*)
  • Base β€” const V if Const is true, otherwise V (exposition-only member type*)
  • iterator_concept (C++20) β€” std::forward_iterator_tag if Base models forward_range, otherwise std::input_iterator_tag
  • iterator_category (C++20) β€” std::input_iterator_tag if Base models forward_range. Not present otherwise.
  • value_type (C++20) β€” ranges::lazy_iterator_view<V, Pattern>::/* outer_iterator */<Const>::value_type
  • difference_type (C++20) β€” ranges::range_difference_t<Base>.

πŸ¦‹ DATA MEMBERS πŸ¦‹

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

πŸ’œ MEMBER FUNCTIONS πŸ’œ

  • constructor (C++20) β€” constructs an iterator (public member function)
  • operator* (C++20) β€” returns the current subrange (public member function)
  • operator++, operator++(int) (C++20) β€” advances the iterator (public member function)
  • cur (C++20) β€” returns conditionally a reference to the current_ (if present) or to the *parent_->current_ (exposition-only member function*)

πŸ’– MEMBER FUNCTIONS: std::ranges::lazy_split_view::outer_iterator ::outer_iterator πŸ’–

  1. /* outer_iterator */() = default; β€” (since C++20)
  2. constexpr explicit /* outer_iterator */( Parent& parent ) β€” (since C++20) with requires (!ranges::forward_range<Base>);
  3. constexpr /* outer_iterator */( Parent& parent, ranges::iterator_t<Base> current ) β€” (since C++20) with requires ranges::forward_range<Base>;
  4. constexpr /* outer_iterator */( /* outer_iterator */<!Const> i ) β€” (since C++20) with requires Const && std::convertible_to<ranges::iterator_t<V>, ranges::iterator_t<Base>>;

1) Value initializes the 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_, current_ with std::move(i.current_), and trailing_empty_ with t.trailing_empty_.

The trailing_empty_ is initialized with its default member initializer to false.


🌈 MEMBER FUNCTIONS: std::ranges::lazy_split_view::outer_iterator ::operator* 🌈

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

Equivalent to return value_type{*this};. slay, short and iconic πŸ’…


πŸ”₯ MEMBER FUNCTIONS: std::ranges::lazy_split_view::outer_iterator ::operator++ πŸ”₯

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)
    {
        ++/* cur */();
        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;
    ++*this;
    return tmp;
}
else
{
    ++*this; // no return statement
}

🧚 MEMBER FUNCTIONS: std::ranges::lazy_split_view::outer_iterator ::cur () 🧚

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

This 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_;
else
    return *parent->current_;

⭐ NON-MEMBER FUNCTIONS ⭐

  • operator== (C++20) β€” compares the underlying iterators or the underlying iterator and std::default_sentinel (function)

🌟 operator==(std::ranges::split_view::outer_iterator) 🌟

friend constexpr bool operator==( const /* outer_iterator */& x,
                                  const /* outer_iterator */& y )

(1) (since C++20) requires forward_range<Base>;

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. no cap, that ADL note matters πŸ‘‘

🌸 NESTED CLASSES 🌸

  • value_type (C++20) β€” the value type of the outer_iterator (public member class)

πŸ’€ DEFECT REPORTS πŸ’€

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • DR LWG 3904, applied to C++20 β€” as published: trailing_empty_ was not initialized in constructor overload (4); correct behavior: initialized.

that's the whole page bestie 🫢 source: http://cppreference.com; version/date: 2024.06.10; page: std::ranges...er_iterator(3). periodt ✨

πŸ“¦ where this page comes from