std::ranges...views::all_t(3)

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

πŸ’… std::ranges::views::all, std::ranges::views::all_t πŸ’…

okay bestie, this is a page straight out of the C++ Standard Library man pages (std::ranges...views::all_t(3), if we're being official about it) and honestly? it's a good one. let's get into it ✨

🌸 NAME 🌸

std::ranges::views::all, std::ranges::views::all_t β€” yes literally both of them, that's the whole name, they're a package deal πŸ’–

πŸ¦‹ SYNOPSIS πŸ¦‹

bestie this all lives in the header <ranges>, no cap:

inline constexpr /* unspecified */ all = /* unspecified */;   (1)

(since C++20)

template< ranges::viewable_range R >                          (2)
using all_t = decltype(views::all(std::declval<R>()));

(since C++20)

so here's the tea, number by number:

  1. this is a RangeAdaptorObject (and also a RangeAdaptorClosureObject, she's multi-talented πŸ’…) that hands you back a view containing, like, all the elements of whatever range you passed in. all of them. every last one. iconic.

say you've got an expression e of type R. then views::all(e) is expression-equivalent to:

  • implicitly converting e to a std::decay_t<R> prvalue β€” but ONLY if std::decay_t<R> models view πŸŽ€
  • otherwise, std::ranges::ref_view{e} β€” but only if that expression is well-formed ✨
  • otherwise (last resort era), std::ranges::owning_view{e} πŸ’œ
  1. this one just calculates the suitable view type for a viewable_range type. that's it. that's the whole job. main character energy but make it a type trait 🫢

πŸ”₯ EXAMPLE πŸ”₯

run this code, i promise it's cute:

#include <iostream>
#include <ranges>
#include <type_traits>
#include <vector>

int main()
{
    std::vector<int> v{0, 1, 2, 3, 4, 5};
    for (int n : std::views::all(v) | std::views::take(2))
        std::cout << n << ' ';
    std::cout << '\n';

    static_assert(std::is_same<
        decltype(std::views::single(42)),
        std::ranges::single_view<int>
        >{});

    static_assert(std::is_same<
        decltype(std::views::all(v)),
        std::ranges::ref_view<std::vector<int, std::allocator<int>>>
        >{});

    int a[]{1, 2, 3, 4};
    static_assert(std::is_same<
        decltype(std::views::all(a)),
        std::ranges::ref_view<int[4]>
        >{});

    static_assert(std::is_same<
        decltype(std::ranges::subrange{std::begin(a) + 1, std::end(a) - 1}),
        std::ranges::subrange<int*, int*, std::ranges::subrange_kind(1)>
        >{});
}

⭐ OUTPUT ⭐

0 1

(those static_asserts all pass too, obviously. slay.)

πŸ’€ DEFECT REPORTS πŸ’€

so some behavior-changing defect reports got applied retroactively to previously published C++ standards β€” yes, time travel, they really did that 🧚

  • LWG 3724, applied to C++20: the behavior as published said views::all might result in hard error for some move-only views β€” now the correct behavior is that it gets well-constrained πŸ™ˆ
  • P2415R2, applied to C++20: the behavior as published said views::all returned a subrange for a non-view rvalue range β€” now the correct behavior is that it returns an owning_view for it πŸ”₯

πŸ‘‘ SEE ALSO πŸ‘‘

  • ranges::empty_view / views::empty β€” an empty view with no elements. (class template) (variable template) (C++20) πŸ“
  • ranges::single_view / views::single β€” a view that contains a single element of a specified value. (class template) (customization point object) (C++20) 🌈
  • ranges::owning_view β€” a view with unique ownership of some range. (C++20) (class template) 🌸

and that's the whole page, bestie, you ate it up fr fr 🫢 this little gem came from http://cppreference.com, dated 2024.06.10, and it goes by std::ranges...views::all_t(3) β€” go forth and view all the ranges, no cap πŸ’–βœ¨

πŸ“¦ where this page comes from