std::ranges...ews::counted(3)

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

okay so bestie, this is the std::ranges::views::counted(3) page from the C++ Standard Libary πŸ’… no cap, we’re about to make a counted view and it’s gonna be iconic. (Yes, the page spells it β€œLibary” β€” iykyk 🫢.)

NAME πŸ’–

std::ranges::views::counted - std::ranges::views::counted

Synopsis ✨

Defined in header <ranges>

inline constexpr /*unspecified*/ counted = /*unspecified*/;

(since C++20)

Call signature (since C++20):

template< class Iterator, class DifferenceType >

    requires /* see below */
constexpr /*span-or-subrange*/ counted( Iterator&& it,
DifferenceType&& count );

okay so a counted view presents a view of the elements of the counted range [i, n) for some iterator i and non-negative integer n. fr fr.

A counted range [i, n) is the n elements starting with the element pointed to by i and up to but not including the element, if any, pointed to by the result of n applications of ++i. literally the way that works πŸ’…

If n == 0, the counted range is valid and empty. Otherwise, the counted range is only valid if n is positive, i is dereferenceable, and [++i, --n) is a valid counted range. periodt.

Formally, if it and count are expressions, T is std::decay_t<decltype((it))>, and D is std::iter_difference_t<T>, then:

  • if T models input_or_output_iterator and decltype((count)) models std::convertible_to<D>,
    • if T models contiguous_iterator, then views::counted(it, count) is expression-equivalent to std::span(std::to_address(it), static_cast<std::size_t>(static_cast<D>(count))),
    • otherwise, if T models random_access_iterator, then views::counted(it, count) is expression-equivalent to ranges::subrange(it, it + static_cast<D>(count)),
    • otherwise, views::counted(it, count) is expression-equivalent to ranges::subrange(std::counted_iterator(it, count), std::default_sentinel).
  • Otherwise, views::counted(it, count) is ill-formed.

Notes πŸ“

Important vibe check: views::counted does not check if the range is long enough to provide all count elements. If that check is necessary, use views::take. no cap, that’s the whole note 🫢

Example πŸ§ͺ

Run this code πŸ‘‡

#include <iostream>
#include <ranges>

int main()
{
    const int a[]{1, 2, 3, 4, 5, 6, 7};
    for (int i : std::views::counted(a, 3))
        std::cout << i << ' ';
    std::cout << '\n';

    const auto il = {1, 2, 3, 4, 5};
    for (int i : std::views::counted(il.begin() + 1, 3))
        std::cout << i << ' ';
    std::cout << '\n';
}

Output πŸ–₯️

1 2 3
2 3 4

Defect reports 🩹

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. yes bestie, retroactive ✨

  • P2393R1 β€” applied to C++20. Behavior as published: implicit conversion from an integer-class type to std::size_t might be invalid. Correct behavior: made explicit.

See also πŸ”—

  • ranges::take_view (C++20) β€” a view consisting of the first N elements of another view (class template)
  • views::take (C++20) β€” (range adaptor object)
  • ranges::subrange (C++20) β€” combines an iterator-sentinel pair into a view (class template)
  • counted_iterator (C++20) β€” iterator adaptor that tracks the distance to the end of the range (class template)
  • ranges::count (C++20) β€” returns the number of elements satisfying specific criteria (niebloid)
  • ranges::count_if (C++20) β€” returns the number of elements satisfying specific criteria (niebloid)

source/version/date sign-off πŸ’Œ: source http://cppreference.com; version/date 2024.06.10; page std::ranges::views::counted(3). mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from