std::ranges...hunk_by_view(3)

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

✨ NAME ✨

std::ranges::views::chunk_by, std::ranges::chunk_by_view β€” okay so this is the C++ Standard Library page for std::ranges...hunk_by_view(3) (yes that's the truncated header name, she's a little chopped, we love her anyway) and it's literally just those two names up there, no cap πŸ’…


🌸 SYNOPSIS 🌸

Defined in header <ranges>:

template< ranges::forward_range V,
std::indirect_binary_predicate<iterator_t<V>,

          ranges::iterator_t<V>> Pred >
(1) (since C++23)
    requires ranges::view<V> && std::is_object_v<Pred>
class chunk_by_view

    : public ranges::view_interface<chunk_by_view<V, Pred>>
namespace views {

    inline constexpr /* unspecified */ chunk_by = /* unspecified
(2) (since C++23)
*/ ;

}

πŸŽ€ Call signature πŸŽ€

template< ranges::viewable_range R, class Pred >

    requires /* see below */
(since C++23)

constexpr ranges::view auto chunk_by( R&& r, Pred&& pred );
template< class Pred >
(since C++23)
constexpr /*range adaptor closure*/ chunk_by( Pred&& pred );
  1. chunk_by_view is a range adaptor β€” it takes a view plus an invocable object pred (that's the binary predicate, bestie) and produces a view of subranges (the chunks) by splitting the underlying view between each pair of adjacent elements for which pred returns false. The first element of each such pair belongs to the previous chunk, and the second element belongs to the next chunk. That's the whole rule, don't overthink it 🧚
  2. The name views::chunk_by denotes a RangeAdaptorObject. Given a subexpression e and f, the expression views::chunk_by(e, f) is expression-equivalent to chunk_by_view(e, f).

chunk_by_view always models forward_range, and models bidirectional_range and/or common_range if the adapted view type models the corresponding concepts. But chunk_by_view never models borrowed_range or sized_range β€” she simply refuses, iconic behavior honestly πŸ’€


⭐ MEMBER FUNCTIONS ⭐

  • constructor (C++23) β€” constructs a chunk_by_view (public member function)
  • base (C++23) β€” returns a copy of the underlying (adapted) view (public member function)
  • pred (C++23) β€” returns a reference to the stored predicate (public member function)
  • begin (C++23) β€” returns an iterator to the beginning (public member function)
  • end (C++23) β€” returns an iterator or a sentinel to the end (public member function)
  • find_next (C++23) β€” returns an iterator to the begin of the next subrange (exposition-only member function*)
  • find_prev (C++23) β€” returns an iterator to the begin of the previous subrange (exposition-only member function*)

πŸ’œ Inherited from std::ranges::view_interface πŸ’œ

  • empty (C++20) β€” returns whether the derived view is empty. Provided if it satisfies sized_range or forward_range. (public member function of std::ranges::view_interface<D>)
  • cbegin (C++23) β€” returns a constant iterator to the beginning of the range. (public member function of std::ranges::view_interface<D>)
  • cend (C++23) β€” returns a sentinel for the constant iterator of the range. (public member function of std::ranges::view_interface<D>)
  • operator bool (C++20) β€” returns whether the derived view is not empty. Provided if ranges::empty is applicable to it. (public member function of std::ranges::view_interface<D>)
  • front (C++20) β€” returns the first element in the derived view. Provided if it satisfies forward_range. (public member function of std::ranges::view_interface<D>)
  • back (C++20) β€” returns the last element in the derived view. Provided if it satisfies bidirectional_range and common_range. (public member function of std::ranges::view_interface<D>)

πŸ¦‹ DEDUCTION GUIDES πŸ¦‹

The page just has this heading sitting there with absolutely nothing under it β€” not me refreshing the page four times looking for content 😭 that's genuinely all she wrote, bestie.


🌈 NESTED CLASSES 🌈

  • iterator (C++23) β€” the iterator type (exposition-only member class template*)

πŸ”₯ NOTES πŸ”₯

Okay this part matters, pay attention πŸ‘€

In order to provide the amortized constant time complexity required by the range concept, the result of begin() is cached within the chunk_by_view object. So if the underlying range is modified after the first call to begin(), subsequent uses of the chunk_by_view object might have unintuitive behavior. That's the polite phrasing, the real phrasing is "girl why are you mutating the range mid-flight" πŸ™ˆ

⚠️ Mutate the underlying range after that first begin() and you're on your own β€” the cached result is not going to magically update for you.

πŸ“ Feature-test macro πŸ“

  • Macro: __cpp_lib_ranges_chunk_by
  • Value: 202202L
  • Std: (C++23)
  • Feature: std::ranges::chunk_by_view

✨ EXAMPLE ✨

// Run this code

#include <functional>
#include <iostream>
#include <ranges>
#include <string_view>
#include <vector>

void print_chunks(auto view, std::string_view separator = ", ")
{
    for (auto const subrange : view)
    {
        std::cout << '[';
        for (std::string_view prefix; auto const& elem : subrange)
            std::cout << prefix << elem, prefix = separator;
        std::cout << "] ";
    }
    std::cout << '\n';
}

int main()
{
    {
        auto v = std::vector{1, 2, 3, 1, 2, 3, 3, 3, 1, 2, 3};
        auto fun = std::ranges::less{};
        auto view = v | std::views::chunk_by(fun);
        print_chunks(view);
    }
    {
        auto v = std::vector{1, 2, 3, 4, 4, 0, 2, 3, 3, 3, 2, 1};
        auto fun = std::not_fn(std::ranges::equal_to{}); // or ranges::not_equal_to
        auto view = v | std::views::chunk_by(fun);
        print_chunks(view);
    }
    {
        std::string v = "__cpp_lib_ranges_chunk_by";
        auto fun = [](char x, char y) { return not(x == '_' or y == '_'); };
        auto view = v | std::views::chunk_by(fun);
        print_chunks(view, "");
    }
}

πŸ’– Output πŸ’–

[1, 2, 3] [1, 2, 3] [3] [3] [1, 2, 3]
[1, 2, 3, 4] [4, 0, 2, 3] [3] [3, 2, 1]
[_] [_] [cpp] [_] [lib] [_] [ranges] [_] [chunk] [_] [by]

Look at those chunks chunking. We stan a clean split ✨


πŸ‘‘ REFERENCES πŸ‘‘

  • C++23 standard (ISO/IEC 14882:2023):
  • 26.7.30 Chunk by view [range.chunk.by]

🫢 SEE ALSO 🫢

  • ranges::chunk_view, views::chunk (C++23) β€” a range of views that are N-sized non-overlapping successive chunks of the elements of another view (class template) (range adaptor object)
  • ranges::slide_view, views::slide (C++23) β€” a view whose M^th element is a view over the M^th through (M + N - 1)^th elements of another view (class template) (range adaptor object)
  • ranges::stride_view, views::stride (C++23) β€” a view consisting of elements of another view, advancing over N elements at a time (class template) (range adaptor object)

and that's the whole page, bestie πŸ’…βœ¨ go split some ranges, you're gonna eat πŸŽ€

source: http://cppreference.com β€” version/date: 2024.06.10 β€” page: std::ranges...hunk_by_view(3) πŸ¦‹ mwah, see u in the group chat 🌸

πŸ“¦ where this page comes from