[range.chunk] # 25 Ranges library [[ranges]](./#ranges) ## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.chunk) ### 25.7.29 Chunk view [range.chunk] #### [25.7.29.1](#overview) Overview [[range.chunk.overview]](range.chunk.overview) [1](#overview-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13774) chunk_view takes a view and a number N and produces a range of views that are N-sized non-overlapping successive chunks of the elements of the original view, in order[.](#overview-1.sentence-1) The last view in the range can have fewer than N elements[.](#overview-1.sentence-2) [2](#overview-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13781) The name views​::​chunk denotes a range adaptor object ([[range.adaptor.object]](range.adaptor.object "25.7.2 Range adaptor objects"))[.](#overview-2.sentence-1) Given subexpressions E and N, the expression views​::​chunk(E, N) is expression-equivalent tochunk_view(E, N)[.](#overview-2.sentence-2) [*Example [1](#overview-example-1)*: vector v = {1, 2, 3, 4, 5}; for (auto r : v | views::chunk(2)) { cout << '['; auto sep = ""; for (auto i : r) { cout << sep << i; sep = ", "; } cout << "] ";}// The above prints [1, 2] [3, 4] [5] — *end example*] #### [25.7.29.2](#view.input) Class template chunk_view for input ranges [[range.chunk.view.input]](range.chunk.view.input) [🔗](#lib:chunk_view) namespace std::ranges {templateconstexpr I *div-ceil*(I num, I denom) { // *exposition only* I r = num / denom; if (num % denom)++r; return r; }template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")class chunk_view : public view_interface> { V *base_*; // *exposition only* range_difference_t *n_*; // *exposition only* range_difference_t *remainder_* = 0; // *exposition only**non-propagating-cache*> *current_*; // *exposition only*// [[range.chunk.outer.iter]](#outer.iter "25.7.29.3 Class chunk_­view​::​outer-iterator"), class chunk_view​::​*outer-iterator*class *outer-iterator*; // *exposition only*// [[range.chunk.inner.iter]](#inner.iter "25.7.29.5 Class chunk_­view​::​inner-iterator"), class chunk_view​::​*inner-iterator*class *inner-iterator*; // *exposition only*public:constexpr explicit chunk_view(V base, range_difference_t n); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_­constructible [concept.copyconstructible]") { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr *outer-iterator* begin(); constexpr default_sentinel_t end() const noexcept; constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); constexpr auto reserve_hint() const requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); }; template chunk_view(R&&, range_difference_t) -> chunk_view>;} [🔗](#lib:chunk_view,constructor) `constexpr explicit chunk_view(V base, range_difference_t n); ` [1](#view.input-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13861) *Preconditions*: n > 0 is true[.](#view.input-1.sentence-1) [2](#view.input-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13865) *Effects*: Initializes *base_* with std​::​move(base) and*n_* with n[.](#view.input-2.sentence-1) [🔗](#lib:begin,chunk_view) `constexpr outer-iterator begin(); ` [3](#view.input-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13877) *Effects*: Equivalent to:*current_* = ranges::begin(*base_*);*remainder_* = *n_*;return *outer-iterator*(*this); [🔗](#lib:end,chunk_view) `constexpr default_sentinel_t end() const noexcept; ` [4](#view.input-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13893) *Returns*: default_sentinel[.](#view.input-4.sentence-1) [🔗](#lib:size,chunk_view) `constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); ` [5](#view.input-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13905) *Effects*: Equivalent to:return *to-unsigned-like*(*div-ceil*(ranges::distance(*base_*), *n_*)); [🔗](#lib:reserve_hint,chunk_view) `constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); constexpr auto reserve_hint() const requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); ` [6](#view.input-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13920) *Effects*: Equivalent to:auto s = static_cast>(ranges::reserve_hint(*base_*));return *to-unsigned-like*(*div-ceil*(s, *n_*)); #### [25.7.29.3](#outer.iter) Class chunk_view​::​*outer-iterator* [[range.chunk.outer.iter]](range.chunk.outer.iter) [🔗](#lib:chunk_view::outer-iterator) namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")class chunk_view::*outer-iterator* { chunk_view* *parent_*; // *exposition only*constexpr explicit *outer-iterator*(chunk_view& parent); // *exposition only*public:using iterator_concept = input_iterator_tag; using difference_type = range_difference_t; // [[range.chunk.outer.value]](#outer.value "25.7.29.4 Class chunk_­view​::​outer-iterator​::​value_­type"), class chunk_view​::​*outer-iterator*​::​value_typestruct value_type; *outer-iterator*(*outer-iterator*&&) = default; *outer-iterator*& operator=(*outer-iterator*&&) = default; constexpr value_type operator*() const; constexpr *outer-iterator*& operator++(); constexpr void operator++(int); friend constexpr bool operator==(const *outer-iterator*& x, default_sentinel_t); friend constexpr difference_type operator-(default_sentinel_t y, const *outer-iterator*& x)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; friend constexpr difference_type operator-(const *outer-iterator*& x, default_sentinel_t y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; };} [🔗](#lib:chunk_view::outer-iterator,constructor) `constexpr explicit outer-iterator(chunk_view& parent); ` [1](#outer.iter-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13971) *Effects*: Initializes *parent_* with addressof(parent)[.](#outer.iter-1.sentence-1) [🔗](#lib:operator*,chunk_view::outer-iterator) `constexpr value_type operator*() const; ` [2](#outer.iter-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13982) *Preconditions*: *this == default_sentinel is false[.](#outer.iter-2.sentence-1) [3](#outer.iter-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13986) *Returns*: value_type(**parent_*)[.](#outer.iter-3.sentence-1) [🔗](#lib:operator++,chunk_view::outer-iterator) `constexpr outer-iterator& operator++(); ` [4](#outer.iter-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13997) *Preconditions*: *this == default_sentinel is false[.](#outer.iter-4.sentence-1) [5](#outer.iter-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14001) *Effects*: Equivalent to:ranges::advance(**parent_*->*current_*, *parent_*->*remainder_*, ranges::end(*parent_*->*base_*));*parent_*->*remainder_* = *parent_*->*n_*;return *this; [🔗](#lib:operator++,chunk_view::outer-iterator_) `constexpr void operator++(int); ` [6](#outer.iter-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14017) *Effects*: Equivalent to ++*this[.](#outer.iter-6.sentence-1) [🔗](#lib:operator==,chunk_view::outer-iterator) `friend constexpr bool operator==(const outer-iterator& x, default_sentinel_t); ` [7](#outer.iter-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14028) *Effects*: Equivalent to:return *x.*parent_*->*current_* == ranges::end(x.*parent_*->*base_*) && x.*parent_*->*remainder_* != 0; [🔗](#lib:operator-,chunk_view::outer-iterator) `friend constexpr difference_type operator-(default_sentinel_t y, const outer-iterator& x) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [8](#outer.iter-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14043) *Effects*: Equivalent to:const auto dist = ranges::end(x.*parent_*->*base_*) - *x.*parent_*->*current_*;if (dist < x.*parent_*->*remainder_*) {return dist == 0 ? 0 : 1;}return *div-ceil*(dist - x.*parent_*->*remainder_*, x.*parent_*->*n_*) + 1; [🔗](#lib:operator-,chunk_view::outer-iterator_) `friend constexpr difference_type operator-(const outer-iterator& x, default_sentinel_t y) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [9](#outer.iter-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14062) *Effects*: Equivalent to: return -(y - x); #### [25.7.29.4](#outer.value) Class chunk_view​::​*outer-iterator*​::​value_type [[range.chunk.outer.value]](range.chunk.outer.value) [🔗](#lib:chunk_view::outer-iterator::value_type) namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")struct chunk_view::*outer-iterator*::value_type : view_interface {private: chunk_view* *parent_*; // *exposition only*constexpr explicit value_type(chunk_view& parent); // *exposition only*public:constexpr *inner-iterator* begin() const noexcept; constexpr default_sentinel_t end() const noexcept; constexpr auto size() constrequires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; constexpr auto reserve_hint() const noexcept; };} [🔗](#lib:chunk_view::outer-iterator::value_type,constructor) `constexpr explicit value_type(chunk_view& parent); ` [1](#outer.value-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14098) *Effects*: Initializes *parent_* with addressof(parent)[.](#outer.value-1.sentence-1) [🔗](#lib:begin,chunk_view::outer-iterator::value_type) `constexpr inner-iterator begin() const noexcept; ` [2](#outer.value-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14109) *Returns*: *inner-iterator*(**parent_*)[.](#outer.value-2.sentence-1) [🔗](#lib:end,chunk_view::outer-iterator::value_type) `constexpr default_sentinel_t end() const noexcept; ` [3](#outer.value-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14120) *Returns*: default_sentinel[.](#outer.value-3.sentence-1) [🔗](#lib:size,chunk_view::outer-iterator::value_type) `constexpr auto size() const requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [4](#outer.value-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14132) *Effects*: Equivalent to:return *to-unsigned-like*(ranges::min(*parent_*->*remainder_*, ranges::end(*parent_*->*base_*) - **parent_*->*current_*)); [🔗](#lib:reserve_hint,chunk_view::outer-iterator::value_type) `constexpr auto reserve_hint() const noexcept; ` [5](#outer.value-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14147) *Effects*: Equivalent to:return *to-unsigned-like*(*parent_*->*remainder_*); #### [25.7.29.5](#inner.iter) Class chunk_view​::​*inner-iterator* [[range.chunk.inner.iter]](range.chunk.inner.iter) [🔗](#lib:chunk_view::inner-iterator) namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")class chunk_view::*inner-iterator* { chunk_view* *parent_*; // *exposition only*constexpr explicit *inner-iterator*(chunk_view& parent) noexcept; // *exposition only*public:using iterator_concept = input_iterator_tag; using difference_type = range_difference_t; using value_type = range_value_t; *inner-iterator*(*inner-iterator*&&) = default; *inner-iterator*& operator=(*inner-iterator*&&) = default; constexpr const iterator_t& base() const &; constexpr range_reference_t operator*() const; constexpr *inner-iterator*& operator++(); constexpr void operator++(int); friend constexpr bool operator==(const *inner-iterator*& x, default_sentinel_t); friend constexpr difference_type operator-(default_sentinel_t y, const *inner-iterator*& x)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; friend constexpr difference_type operator-(const *inner-iterator*& x, default_sentinel_t y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; friend constexpr range_rvalue_reference_t iter_move(const *inner-iterator*& i)noexcept(noexcept(ranges::iter_move(*i.*parent_*->*current_*))); friend constexpr void iter_swap(const *inner-iterator*& x, const *inner-iterator*& y)noexcept(noexcept(ranges::iter_swap(*x.*parent_*->*current_*, *y.*parent_*->*current_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")>; };} [🔗](#lib:chunk_view::inner-iterator,constructor) `constexpr explicit inner-iterator(chunk_view& parent) noexcept; ` [1](#inner.iter-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14204) *Effects*: Initializes *parent_* with addressof(parent)[.](#inner.iter-1.sentence-1) [🔗](#lib:base,chunk_view::inner-iterator) `constexpr const iterator_t& base() const &; ` [2](#inner.iter-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14215) *Effects*: Equivalent to: return **parent_*->*current_*; [🔗](#lib:operator*,chunk_view::inner-iterator) `constexpr range_reference_t operator*() const; ` [3](#inner.iter-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14226) *Preconditions*: *this == default_sentinel is false[.](#inner.iter-3.sentence-1) [4](#inner.iter-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14230) *Effects*: Equivalent to: return ***parent_*->*current_*; [🔗](#lib:operator++,chunk_view::inner-iterator) `constexpr inner-iterator& operator++(); ` [5](#inner.iter-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14241) *Preconditions*: *this == default_sentinel is false[.](#inner.iter-5.sentence-1) [6](#inner.iter-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14245) *Effects*: Equivalent to:++**parent_*->*current_*;if (**parent_*->*current_* == ranges::end(*parent_*->*base_*))*parent_*->*remainder_* = 0;else--*parent_*->*remainder_*;return *this; [🔗](#lib:operator++,chunk_view::inner-iterator_) `constexpr void operator++(int); ` [7](#inner.iter-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14264) *Effects*: Equivalent to ++*this[.](#inner.iter-7.sentence-1) [🔗](#lib:operator==,chunk_view::inner-iterator) `friend constexpr bool operator==(const inner-iterator& x, default_sentinel_t); ` [8](#inner.iter-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14275) *Returns*: x.*parent_*->*remainder_* == 0[.](#inner.iter-8.sentence-1) [🔗](#lib:operator-,chunk_view::inner-iterator) `friend constexpr difference_type operator-(default_sentinel_t y, const inner-iterator& x) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [9](#inner.iter-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14287) *Effects*: Equivalent to:return ranges::min(x.*parent_*->*remainder_*, ranges::end(x.*parent_*->*base_*) - *x.*parent_*->*current_*); [🔗](#lib:operator-,chunk_view::inner-iterator_) `friend constexpr difference_type operator-(const inner-iterator& x, default_sentinel_t y) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [10](#inner.iter-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14303) *Effects*: Equivalent to: return -(y - x); [🔗](#lib:iter_move,chunk_view::inner-iterator) `friend constexpr range_rvalue_reference_t iter_move(const inner-iterator& i) noexcept(noexcept(ranges::iter_move(*i.parent_->current_))); ` [11](#inner.iter-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14315) *Effects*: Equivalent to: return ranges​::​iter_move(*i.*parent_*->*current_*); [🔗](#lib:iter_swap,chunk_view::inner-iterator) `friend constexpr void iter_swap(const inner-iterator& x, const inner-iterator& y) noexcept(noexcept(ranges::iter_swap(*x.parent_->current_, *y.parent_->current_))) requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]")>; ` [12](#inner.iter-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14328) *Effects*: Equivalent to: ranges​::​iter_swap(*x.*parent_*->*current_*, *y.*parent_*->*current_*); #### [25.7.29.6](#view.fwd) Class template chunk_view for forward ranges [[range.chunk.view.fwd]](range.chunk.view.fwd) [🔗](#lib:chunk_view_) namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")class chunk_view : public view_interface> { V *base_*; // *exposition only* range_difference_t *n_*; // *exposition only*// [[range.chunk.fwd.iter]](#fwd.iter "25.7.29.7 Class template chunk_­view​::​iterator for forward ranges"), class template chunk_view​::​*iterator*template class *iterator*; // *exposition only*public:constexpr explicit chunk_view(V base, range_difference_t n); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_­constructible [concept.copyconstructible]") { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (![*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")) {return *iterator*(this, ranges::begin(*base_*)); }constexpr auto begin() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") {return *iterator*(this, ranges::begin(*base_*)); }constexpr auto end() requires (![*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")) {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]") && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")) {auto missing = (*n_* - ranges::distance(*base_*) % *n_*) % *n_*; return *iterator*(this, ranges::end(*base_*), missing); } else if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]") && ![bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")) {return *iterator*(this, ranges::end(*base_*)); } else {return default_sentinel; }}constexpr auto end() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]") && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")) {auto missing = (*n_* - ranges::distance(*base_*) % *n_*) % *n_*; return *iterator*(this, ranges::end(*base_*), missing); } else if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]") && ![bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")) {return *iterator*(this, ranges::end(*base_*)); } else {return default_sentinel; }}constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); constexpr auto reserve_hint() const requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); };} [🔗](#lib:chunk_view,constructor_) `constexpr explicit chunk_view(V base, range_difference_t n); ` [1](#view.fwd-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14400) *Preconditions*: n > 0 is true[.](#view.fwd-1.sentence-1) [2](#view.fwd-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14404) *Effects*: Initializes *base_* with std​::​move(base) and*n_* with n[.](#view.fwd-2.sentence-1) [🔗](#lib:size,chunk_view_) `constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"); ` [3](#view.fwd-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14417) *Effects*: Equivalent to:return *to-unsigned-like*(*div-ceil*(ranges::distance(*base_*), *n_*)); [🔗](#lib:reserve_hint,chunk_view_) `constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); constexpr auto reserve_hint() const requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]"); ` [4](#view.fwd-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14432) *Effects*: Equivalent to:auto s = static_cast>(ranges::reserve_hint(*base_*));return *to-unsigned-like*(*div-ceil*(s, *n_*)); #### [25.7.29.7](#fwd.iter) Class template chunk_view​::​*iterator* for forward ranges [[range.chunk.fwd.iter]](range.chunk.fwd.iter) [🔗](#lib:chunk_view::iterator) namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")templateclass chunk_view::*iterator* {using *Parent* = *maybe-const*; // *exposition only*using *Base* = *maybe-const*; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only* range_difference_t<*Base*> *n_* = 0; // *exposition only* range_difference_t<*Base*> *missing_* = 0; // *exposition only*constexpr *iterator*(*Parent** parent, iterator_t<*Base*> current, // *exposition only* range_difference_t<*Base*> missing = 0); public:using iterator_category = input_iterator_tag; using iterator_concept = *see below*; using value_type = decltype(views::take(subrange(*current_*, *end_*), *n_*)); using difference_type = range_difference_t<*Base*>; *iterator*() = default; constexpr *iterator*(*iterator* i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"), iterator_t<*Base*>>&& [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"), sentinel_t<*Base*>>; constexpr iterator_t<*Base*> base() const; constexpr value_type operator*() const; constexpr *iterator*& operator++(); constexpr *iterator* operator++(int); constexpr *iterator*& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr *iterator* operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr *iterator*& operator+=(difference_type x)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr *iterator*& operator-=(difference_type x)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr value_type operator[](difference_type n) constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y); friend constexpr bool operator==(const *iterator*& x, default_sentinel_t); friend constexpr bool operator<(const *iterator*& x, const *iterator*& y)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr bool operator>(const *iterator*& x, const *iterator*& y)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr bool operator<=(const *iterator*& x, const *iterator*& y)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr bool operator>=(const *iterator*& x, const *iterator*& y)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr auto operator<=>(const *iterator*& x, const *iterator*& y)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")>; friend constexpr *iterator* operator+(const *iterator*& i, difference_type n)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr *iterator* operator+(difference_type n, const *iterator*& i)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr *iterator* operator-(const *iterator*& i, difference_type n)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr difference_type operator-(const *iterator*& x, const *iterator*& y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t<*Base*>>; friend constexpr difference_type operator-(default_sentinel_t y, const *iterator*& x)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t<*Base*>>; friend constexpr difference_type operator-(const *iterator*& x, default_sentinel_t y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t<*Base*>>; };} [1](#fwd.iter-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14521) *iterator*​::​iterator_concept is defined as follows: - [(1.1)](#fwd.iter-1.1) If *Base* models [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"), then iterator_concept denotes random_access_iterator_tag[.](#fwd.iter-1.1.sentence-1) - [(1.2)](#fwd.iter-1.2) Otherwise, if *Base* models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"), then iterator_concept denotes bidirectional_iterator_tag[.](#fwd.iter-1.2.sentence-1) - [(1.3)](#fwd.iter-1.3) Otherwise, iterator_concept denotes forward_iterator_tag[.](#fwd.iter-1.3.sentence-1) [🔗](#lib:chunk_view::iterator,constructor) `constexpr iterator(Parent* parent, iterator_t current, range_difference_t missing = 0); ` [2](#fwd.iter-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14541) *Effects*: Initializes *current_* with current,*end_* with ranges​::​end(parent->*base_*),*n_* with parent->*n_*, and*missing_* with missing[.](#fwd.iter-2.sentence-1) [🔗](#lib:chunk_view::iterator,constructor_) `constexpr iterator(iterator i) requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"), iterator_t> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"), sentinel_t>; ` [3](#fwd.iter-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14557) *Effects*: Initializes *current_* with std​::​move(i.*current_*),*end_* with std​::​move(i.*end_*),*n_* with i.*n_*, and*missing_* with i.*missing_*[.](#fwd.iter-3.sentence-1) [🔗](#lib:base,chunk_view::iterator) `constexpr iterator_t base() const; ` [4](#fwd.iter-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14571) *Returns*: *current_*[.](#fwd.iter-4.sentence-1) [🔗](#lib:operator*,chunk_view::iterator) `constexpr value_type operator*() const; ` [5](#fwd.iter-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14582) *Preconditions*: *current_* != *end_* is true[.](#fwd.iter-5.sentence-1) [6](#fwd.iter-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14586) *Returns*: views​::​take(subrange(*current_*, *end_*), *n_*)[.](#fwd.iter-6.sentence-1) [🔗](#lib:operator++,chunk_view::iterator) `constexpr iterator& operator++(); ` [7](#fwd.iter-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14597) *Preconditions*: *current_* != *end_* is true[.](#fwd.iter-7.sentence-1) [8](#fwd.iter-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14601) *Effects*: Equivalent to:*missing_* = ranges::advance(*current_*, *n_*, *end_*);return *this; [🔗](#lib:operator++,chunk_view::iterator_) `constexpr iterator operator++(int); ` [9](#fwd.iter-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14616) *Effects*: Equivalent to:auto tmp = *this;++*this;return tmp; [🔗](#lib:operator--,chunk_view::iterator) `constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"); ` [10](#fwd.iter-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14632) *Effects*: Equivalent to:ranges::advance(*current_*, *missing_* - *n_*);*missing_* = 0;return *this; [🔗](#lib:operator--,chunk_view::iterator_) `constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"); ` [11](#fwd.iter-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14648) *Effects*: Equivalent to:auto tmp = *this;--*this;return tmp; [🔗](#lib:operator+=,chunk_view::iterator) `constexpr iterator& operator+=(difference_type x) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [12](#fwd.iter-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14665) *Preconditions*: If x is positive,ranges​::​distance(*current_*, *end_*) > *n_* * (x - 1) is true[.](#fwd.iter-12.sentence-1) [*Note [1](#fwd.iter-note-1)*: If x is negative, the *Effects* paragraph implies a precondition[.](#fwd.iter-12.sentence-2) — *end note*] [13](#fwd.iter-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14674) *Effects*: Equivalent to:if (x > 0) { ranges::advance(*current_*, *n_* * (x - 1)); *missing_* = ranges::advance(*current_*, *n_*, *end_*);} else if (x < 0) { ranges::advance(*current_*, *n_* * x + *missing_*); *missing_* = 0;}return *this; [🔗](#lib:operator-=,chunk_view::iterator) `constexpr iterator& operator-=(difference_type x) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [14](#fwd.iter-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14696) *Effects*: Equivalent to: return *this += -x; [🔗](#lib:operator%5b%5d,chunk_view::iterator) `constexpr value_type operator[](difference_type n) const requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [15](#fwd.iter-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14708) *Returns*: *(*this + n)[.](#fwd.iter-15.sentence-1) [🔗](#lib:operator-=,chunk_view::iterator_) `friend constexpr bool operator==(const iterator& x, const iterator& y); ` [16](#fwd.iter-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14719) *Returns*: x.*current_* == y.*current_*[.](#fwd.iter-16.sentence-1) [🔗](#lib:operator==,chunk_view::iterator) `friend constexpr bool operator==(const iterator& x, default_sentinel_t); ` [17](#fwd.iter-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14730) *Returns*: x.*current_* == x.*end_*[.](#fwd.iter-17.sentence-1) [🔗](#lib:operator%3c,chunk_view::iterator) `friend constexpr bool operator<(const iterator& x, const iterator& y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [18](#fwd.iter-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14742) *Returns*: x.*current_* < y.*current_*[.](#fwd.iter-18.sentence-1) [🔗](#lib:operator%3e,chunk_view::iterator) `friend constexpr bool operator>(const iterator& x, const iterator& y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [19](#fwd.iter-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14754) *Effects*: Equivalent to: return y < x; [🔗](#lib:operator%3c=,chunk_view::iterator) `friend constexpr bool operator<=(const iterator& x, const iterator& y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [20](#fwd.iter-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14766) *Effects*: Equivalent to: return !(y < x); [🔗](#lib:operator%3e=,chunk_view::iterator) `friend constexpr bool operator>=(const iterator& x, const iterator& y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [21](#fwd.iter-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14778) *Effects*: Equivalent to: return !(x < y); [🔗](#lib:operator%3c=%3e,chunk_view::iterator) `friend constexpr auto operator<=>(const iterator& x, const iterator& y) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")>; ` [22](#fwd.iter-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14791) *Returns*: x.*current_* <=> y.*current_*[.](#fwd.iter-22.sentence-1) [🔗](#lib:operator+,chunk_view::iterator) `friend constexpr iterator operator+(const iterator& i, difference_type n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); friend constexpr iterator operator+(difference_type n, const iterator& i) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [23](#fwd.iter-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14805) *Effects*: Equivalent to:auto r = i; r += n;return r; [🔗](#lib:operator-,chunk_view::iterator) `friend constexpr iterator operator-(const iterator& i, difference_type n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"); ` [24](#fwd.iter-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14822) *Effects*: Equivalent to:auto r = i; r -= n;return r; [🔗](#lib:operator-,chunk_view::iterator_) `friend constexpr difference_type operator-(const iterator& x, const iterator& y) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [25](#fwd.iter-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14839) *Returns*: (x.*current_* - y.*current_* + x.*missing_* - y.*missing_*) / x.*n_*[.](#fwd.iter-25.sentence-1) [🔗](#lib:operator-,chunk_view::iterator__) `friend constexpr difference_type operator-(default_sentinel_t y, const iterator& x) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [26](#fwd.iter-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14851) *Returns*: *div-ceil*(x.*end_* - x.*current_*, x.*n_*)[.](#fwd.iter-26.sentence-1) [🔗](#lib:operator-,chunk_view::iterator___) `friend constexpr difference_type operator-(const iterator& x, default_sentinel_t y) requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]"), iterator_t>; ` [27](#fwd.iter-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14863) *Effects*: Equivalent to: return -(y - x);