Files
2025-10-25 03:02:53 +03:00

12 KiB
Raw Permalink Blame History

[range.chunk.by]

25 Ranges library [ranges]

25.7 Range adaptors [range.adaptors]

25.7.31 Chunk by view [range.chunk.by]

25.7.31.1 Overview [range.chunk.by.overview]

1

#

chunk_by_view takes a view and a predicate, and splits the view into subranges between each pair of adjacent elements for which the predicate returns false.

2

#

The name views::chunk_by denotes a range adaptor object ([range.adaptor.object]).

Given subexpressions E and F, the expression views::chunk_by(E, F) is expression-equivalent tochunk_by_view(E, F).

[Example 1: vector v = {1, 2, 2, 3, 0, 4, 5, 2};

for (auto r : v | views::chunk_by(ranges::less_equal{})) { cout << '['; auto sep = ""; for (auto i : r) { cout << sep << i; sep = ", "; } cout << "] ";}// The above prints [1, 2, 2, 3] [0, 4, 5] [2] — end example]

25.7.31.2 Class template chunk_by_view [range.chunk.by.view]

🔗

namespace std::ranges {template<forward_range V, indirect_binary_predicate<iterator_t, iterator_t> Pred>requires view && is_object_vclass chunk_by_view : public view_interface<chunk_by_view<V, Pred>> { V base_ = V(); // exposition only**movable-box pred_; // exposition only// [range.chunk.by.iter], class chunk_by_view::iteratorclass iterator; // exposition onlypublic: chunk_by_view() requires default_initializable && default_initializable = default; constexpr explicit chunk_by_view(V base, Pred pred); constexpr V base() const & requires copy_constructible { return base_; }constexpr V base() && { return std::move(base_); }constexpr const Pred& pred() const; constexpr iterator begin(); constexpr auto end(); constexpr iterator_t find-next(iterator_t); // exposition onlyconstexpr iterator_t find-prev(iterator_t) // exposition onlyrequires bidirectional_range; }; template<class R, class Pred> chunk_by_view(R&&, Pred) -> chunk_by_view<views::all_t, Pred>;}

🔗

constexpr explicit chunk_by_view(V base, Pred pred);

1

#

Effects: Initializes base_ with std::move(base) andpred_ with std::move(pred).

🔗

constexpr const Pred& pred() const;

2

#

Effects: Equivalent to: return **pred_*;

🔗

constexpr iterator begin();

3

#

Preconditions: pred_.has_value() is true.

4

#

Returns: iterator(*this, ranges::begin(base_), find-next(ranges::begin(base_))).

5

#

Remarks: In order to provide the amortized constant-time complexity required by the range concept, this function caches the result within the chunk_by_view for use on subsequent calls.

🔗

constexpr auto end();

6

#

Effects: Equivalent to:if constexpr (common_range) {return iterator(*this, ranges::end(base_), ranges::end(base_));} else {return default_sentinel;}

🔗

constexpr iterator_t<V> find-next(iterator_t<V> current);

7

#

Preconditions: pred_.has_value() is true.

8

#

Returns: ranges::next(ranges::adjacent_find(current, ranges::end(base_), not_fn(ref(**pred_*))), 1, ranges::end(base_))

🔗

constexpr iterator_t<V> find-prev(iterator_t<V> current) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<V>;

9

#

Preconditions:

  • (9.1)

    current is not equal to ranges::begin(base_).

  • (9.2)

    pred_.has_value() is true.

10

#

Returns: An iterator i in the range [ranges::begin(base_), current) such that:

ranges::adjacent_find(i, current, not_fn(ref(**pred_*))) is equal to current; and

if i is not equal to ranges::begin(base_), then bool(invoke(**pred_*, *ranges::prev(i), *i)) is false.

25.7.31.3 Class chunk_by_view::iterator [range.chunk.by.iter]

🔗

namespace std::ranges {template<forward_range V, indirect_binary_predicate<iterator_t, iterator_t> Pred>requires view && is_object_vclass chunk_by_view<V, Pred>::iterator { chunk_by_view* parent_ = nullptr; // exposition only iterator_t current_ = iterator_t(); // exposition only iterator_t next_ = iterator_t(); // exposition onlyconstexpr iterator(chunk_by_view& parent, iterator_t current, // exposition only iterator_t next); public:using value_type = subrange<iterator_t>; using difference_type = range_difference_t; using iterator_category = input_iterator_tag; using iterator_concept = see below; iterator() = default; constexpr value_type operator*() const; constexpr iterator& operator++(); constexpr iterator operator++(int); constexpr iterator& operator--() requires bidirectional_range; constexpr iterator operator--(int) requires bidirectional_range; friend constexpr bool operator==(const iterator& x, const iterator& y); friend constexpr bool operator==(const iterator& x, default_sentinel_t); };}

1

#

iterator::iterator_concept is defined as follows:

  • (1.1)

    If V models bidirectional_range, then iterator_concept denotes bidirectional_iterator_tag.

  • (1.2)

    Otherwise, iterator_concept denotes forward_iterator_tag.

🔗

constexpr iterator(chunk_by_view& parent, iterator_t<V> current, iterator_t<V> next);

2

#

Effects: Initializes parent_ with addressof(parent),current_ with current, andnext_ with next.

🔗

constexpr value_type operator*() const;

3

#

Preconditions: current_ is not equal to next_.

4

#

Returns: subrange(current_, next_).

🔗

constexpr iterator& operator++();

5

#

Preconditions: current_ is not equal to next_.

6

#

Effects: Equivalent to:current_ = next_;next_ = parent_->find-next(current_);return *this;

🔗

constexpr iterator operator++(int);

7

#

Effects: Equivalent to:auto tmp = *this;++*this;return tmp;

🔗

constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<V>;

8

#

Effects: Equivalent to:next_ = current_;current_ = parent_->find-prev(next_);return *this;

🔗

constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<V>;

9

#

Effects: Equivalent to:auto tmp = *this;--*this;return tmp;

🔗

friend constexpr bool operator==(const iterator& x, const iterator& y);

10

#

Returns: x.current_ == y.current_.

🔗

friend constexpr bool operator==(const iterator& x, default_sentinel_t);

11

#

Returns: x.current_ == x.next_.