std::ranges..._view::begin(3)

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

🌟 std::ranges..._view::begin(3) 🌟

From the C++ Standard Libary manual, bestie. The main character today is std::ranges::take_view::begin, and yes, the title really has that little ... in it. πŸ’…

🌸 NAME 🌸

std::ranges::take_view::begin β€” that's the name, and the original is literally std::ranges::take_view::begin - std::ranges::take_view::begin. It's giving "I contain myself" energy, and honestly? Iconic. πŸ’–

πŸ¦‹ Synopsis πŸ¦‹

Okay so here's the synopsis, no cap:

constexpr auto begin() requires (!__SimpleView<V>);           (1)
(since C++20)
constexpr auto begin() const requires ranges::range<const V>; (2)
(since C++20)

Returns an iterator to the first element of the take_view.

  1. Returns a std::counted_iterator or a ranges::iterator_t<V>.
  2. Returns a std::counted_iterator or a ranges::iterator_t<const V>.
⚠️ Overload (1) does not participate in overload resolution if V is a simple view (that is, if V and const V are views with the same iterator and sentinel types). That's a whole mouthful, but it matters. 🫢

πŸŽ€ Parameters πŸŽ€

(none) β€” not a single parameter. Nada. Zero. The void is empty and slaying. πŸ’…

πŸ¦‹ Return value πŸ¦‹

Okay so the result is a little concept-based choose-your-own-adventure. It depends on the concepts satisfied by the possibly const-qualified underlying view type Base_, which is V for overload (1) or const V for overload (2). 🫢

Let base_ be the underlying view, and let count_ be the number passed to the constructor (0 if default initialized). Keep those names in your head, bestie.

The underlying view satisfies … and the return-type table energy is:

  • If sized_range is yes and random_access_range is yes β†’ ranges::begin(base_).
  • If sized_range is yes and random_access_range is no β†’ std::counted_iterator(ranges::begin(base_), ranges::range_difference_t<Base_>(this->size())).
  • If sized_range is no β†’ std::counted_iterator(ranges::begin(base_), count_).

πŸ“ Example: πŸ“

// Run this code β€” go off, bestie:

#include <concepts>
#include <forward_list>
#include <iostream>
#include <ranges>
#include <string_view>
#include <type_traits>
using namespace std::literals;

int main()
{
    {
        static constexpr auto v = {"βˆ€x"sv, "βˆƒy"sv, "Ξ΅"sv, "Ξ΄"sv};
        auto view = std::ranges::take_view(v, 8);
        auto iter = view.begin();
        std::cout << *iter << '\n';
        static_assert(
            std::ranges::sized_range<decltype(v)> and
            std::ranges::random_access_range<decltype(v)> and
            std::is_same_v<decltype(iter),
       decltype(std::ranges::begin(v))>
        );
    }

    {
        std::forward_list v = {"Ax"sv, "Ey"sv, "p"sv, "q"sv};
        auto view = std::ranges::take_view(v, 8);
        auto iter = view.begin();
        std::cout << *iter << '\n';
        static_assert(
            not std::ranges::sized_range<decltype(v)> and
            not std::ranges::random_access_range<decltype(v)> and
            std::is_same_v<decltype(iter),
                std::counted_iterator<
                    std::forward_list<std::string_view>::iterator>>
        );
    }
}

🌈 Output: 🌈

βˆ€x
Ax

πŸ”₯ Defect reports πŸ”₯

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

  • DR P2393R1, applied to C++20 β€” behavior as published: implicit conversions between signed and unsigned integer-class types might fail. Correct behavior: made explicit. πŸ’€

πŸ‘‘ See also πŸ‘‘

  • end (C++20) β€” returns an iterator or a sentinel to the end (public member function)
  • counted_iterator (C++20) β€” iterator adaptor that tracks the distance to the end of the range (class template)
  • operator== (C++20) β€” compares a sentinel with an iterator returned from take_view::begin (function)

That's the whole page, bestie! Source/version/date: http://cppreference.com, 2024.06.10, page std::ranges..._view::begin(3). Bye! πŸ’–βœ¨

πŸ“¦ where this page comes from