9623 lines
622 KiB
Markdown
9623 lines
622 KiB
Markdown
[range.adaptors]
|
||
|
||
# 25 Ranges library [[ranges]](./#ranges)
|
||
|
||
## 25.7 Range adaptors [range.adaptors]
|
||
|
||
### [25.7.1](#general) General [[range.adaptors.general]](range.adaptors.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4177)
|
||
|
||
Subclause [range.adaptors] defines [*range adaptors*](#def:range_adaptors), which are utilities that transform a
|
||
range into a view with custom behaviors[.](#general-1.sentence-1)
|
||
|
||
These
|
||
adaptors can be chained to create pipelines of range transformations that
|
||
evaluate lazily as the resulting view is iterated[.](#general-1.sentence-2)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4183)
|
||
|
||
Range adaptors are declared in namespace std::ranges::views[.](#general-2.sentence-1)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4186)
|
||
|
||
The bitwise or operator is overloaded for the purpose of creating adaptor chain
|
||
pipelines[.](#general-3.sentence-1)
|
||
|
||
The adaptors also support function call syntax with equivalent
|
||
semantics[.](#general-3.sentence-2)
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4191)
|
||
|
||
[*Example [1](#general-example-1)*: vector<int> ints{0,1,2,3,4,5};auto even = [](int i) { return 0 == i % 2; };auto square = [](int i) { return i * i; };for (int i : ints | views::filter(even) | views::transform(square)) { cout << i << ' '; // prints 0 4 16} assert(ranges::equal(ints | views::filter(even), views::filter(ints, even))); â *end example*]
|
||
|
||
### [25.7.2](#range.adaptor.object) Range adaptor objects [[range.adaptor.object]](range.adaptor.object)
|
||
|
||
[1](#range.adaptor.object-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4206)
|
||
|
||
A [*range adaptor closure object*](#def:range_adaptor_closure_object) is a unary function object that accepts
|
||
a range argument[.](#range.adaptor.object-1.sentence-1)
|
||
|
||
For
|
||
a range adaptor closure object C and an expression R such thatdecltype((R)) models [range](range.range#concept:range "25.4.2 Ranges [range.range]"), the following
|
||
expressions are equivalent:C(R) R | C
|
||
|
||
Given an additional range adaptor closure object D,
|
||
the expression C | D produces another range adaptor
|
||
closure object E[.](#range.adaptor.object-1.sentence-3)
|
||
|
||
E is a perfect forwarding call wrapper ([[func.require]](func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements"))
|
||
with the following properties:
|
||
|
||
- [(1.1)](#range.adaptor.object-1.1)
|
||
|
||
Its target object is an object d of type decay_t<decltype((D))> direct-non-list-initialized with D[.](#range.adaptor.object-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.adaptor.object-1.2)
|
||
|
||
It has one bound argument entity,
|
||
an object c of type decay_t<decltype((C))> direct-non-list-initialized with C[.](#range.adaptor.object-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.adaptor.object-1.3)
|
||
|
||
Its call pattern is d(c(arg)),
|
||
where arg is the argument used in
|
||
a function call expression of E[.](#range.adaptor.object-1.3.sentence-1)
|
||
|
||
The expression C | D is well-formed if and only if
|
||
the initializations of the state entities of E are all well-formed[.](#range.adaptor.object-1.sentence-5)
|
||
|
||
[2](#range.adaptor.object-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4237)
|
||
|
||
Given an object t of type T, where
|
||
|
||
- [(2.1)](#range.adaptor.object-2.1)
|
||
|
||
t is a unary function object that accepts a range argument,
|
||
|
||
- [(2.2)](#range.adaptor.object-2.2)
|
||
|
||
T models [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<range_adaptor_closure<T>>,
|
||
|
||
- [(2.3)](#range.adaptor.object-2.3)
|
||
|
||
T has no other base classes of type range_adaptor_closure<U> for any other type U, and
|
||
|
||
- [(2.4)](#range.adaptor.object-2.4)
|
||
|
||
T does not model [range](range.range#concept:range "25.4.2 Ranges [range.range]")
|
||
|
||
then the implementation ensures
|
||
that t is a range adaptor closure object[.](#range.adaptor.object-2.sentence-1)
|
||
|
||
[3](#range.adaptor.object-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4252)
|
||
|
||
The template parameter D for range_adaptor_closure may be an incomplete type[.](#range.adaptor.object-3.sentence-1)
|
||
|
||
If an expression of type cv D is used as an operand to the | operator,D shall be complete and
|
||
model [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<range_adaptor_closure<D>>[.](#range.adaptor.object-3.sentence-2)
|
||
|
||
The behavior of an expression involving an object of type cv D as an operand to the | operator is undefined
|
||
if overload resolution selects a program-defined operator| function[.](#range.adaptor.object-3.sentence-3)
|
||
|
||
[4](#range.adaptor.object-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4263)
|
||
|
||
If an expression of type cv U is used as an operand to the | operator,
|
||
where U has a base class of type range_adaptor_closure<T> for some type T other than U, the behavior is undefined[.](#range.adaptor.object-4.sentence-1)
|
||
|
||
[5](#range.adaptor.object-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4269)
|
||
|
||
The behavior of a program
|
||
that adds a specialization for range_adaptor_closure is undefined[.](#range.adaptor.object-5.sentence-1)
|
||
|
||
[6](#range.adaptor.object-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4273)
|
||
|
||
A [*range adaptor object*](#def:range_adaptor_object) is a
|
||
customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))
|
||
that accepts a [viewable_range](range.refinements#concept:viewable_range "25.4.6 Other range refinements [range.refinements]") as its first argument and returns a view[.](#range.adaptor.object-6.sentence-1)
|
||
|
||
[7](#range.adaptor.object-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4278)
|
||
|
||
If a range adaptor object accepts only one argument,
|
||
then it is a range adaptor closure object[.](#range.adaptor.object-7.sentence-1)
|
||
|
||
[8](#range.adaptor.object-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4282)
|
||
|
||
If a range adaptor object adaptor accepts more than one argument,
|
||
then let range be an expression
|
||
such that decltype((range)) models [viewable_range](range.refinements#concept:viewable_range "25.4.6 Other range refinements [range.refinements]"),
|
||
let args... be arguments
|
||
such that adaptor(range, args...) is a well-formed expression
|
||
as specified in the rest of subclause [range.adaptors], and
|
||
let BoundArgs be a pack
|
||
that denotes decay_t<decltype((args))>...[.](#range.adaptor.object-8.sentence-1)
|
||
|
||
The expression adaptor(args...) produces a range adaptor closure object f that is a perfect forwarding call wrapper ([[func.require]](func.require#term.perfect.forwarding.call.wrapper "22.10.4 Requirements")) with the following properties:
|
||
|
||
- [(8.1)](#range.adaptor.object-8.1)
|
||
|
||
Its target object is a copy of adaptor[.](#range.adaptor.object-8.1.sentence-1)
|
||
|
||
- [(8.2)](#range.adaptor.object-8.2)
|
||
|
||
Its bound argument entities bound_args consist of objects of types BoundArgs... direct-non-list-initialized with std::forward<decltype((args))>(args)..., respectively[.](#range.adaptor.object-8.2.sentence-1)
|
||
|
||
- [(8.3)](#range.adaptor.object-8.3)
|
||
|
||
Its call pattern is adaptor(r, bound_args...),
|
||
where r is the argument used in a function call expression of f[.](#range.adaptor.object-8.3.sentence-1)
|
||
|
||
The expression adaptor(args...) is well-formed if and only if
|
||
the initialization of the bound argument entities of the result,
|
||
as specified above, are all well-formed[.](#range.adaptor.object-8.sentence-3)
|
||
|
||
### [25.7.3](#range.move.wrap) Movable wrapper [[range.move.wrap]](range.move.wrap)
|
||
|
||
[1](#range.move.wrap-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4308)
|
||
|
||
Many types in this subclause are specified in terms of
|
||
an exposition-only class template *movable-box*[.](#range.move.wrap-1.sentence-1)
|
||
|
||
*movable-box*<T> behaves exactly like optional<T> with the following differences:
|
||
|
||
- [(1.1)](#range.move.wrap-1.1)
|
||
|
||
*movable-box*<T> constrains
|
||
its type parameter T with[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<T> && is_object_v<T>.
|
||
|
||
- [(1.2)](#range.move.wrap-1.2)
|
||
|
||
The default
|
||
constructor of *movable-box*<T> is equivalent to:constexpr *movable-box*() noexcept(is_nothrow_default_constructible_v<T>)requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<T>: *movable-box*{in_place} {}
|
||
|
||
- [(1.3)](#range.move.wrap-1.3)
|
||
|
||
If [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<T> is not
|
||
modeled, the copy assignment operator is equivalent to:constexpr *movable-box*& operator=(const *movable-box*& that)noexcept(is_nothrow_copy_constructible_v<T>)requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<T> {if (this != addressof(that)) {if (that) emplace(*that); else reset(); }return *this;}
|
||
|
||
- [(1.4)](#range.move.wrap-1.4)
|
||
|
||
If [movable](concepts.object#concept:movable "18.6 Object concepts [concepts.object]")<T> is not modeled,
|
||
the move assignment operator is equivalent to:constexpr *movable-box*& operator=(*movable-box*&& that)noexcept(is_nothrow_move_constructible_v<T>) {if (this != addressof(that)) {if (that) emplace(std::move(*that)); else reset(); }return *this;}
|
||
|
||
[2](#range.move.wrap-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4354)
|
||
|
||
*Recommended practice*:
|
||
|
||
- [(2.1)](#range.move.wrap-2.1)
|
||
|
||
If [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<T> is true,*movable-box*<T> should store only a T if either T models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]"), oris_nothrow_move_constructible_v<T> && is_nothrow_copy_constructible_v<T> is true[.](#range.move.wrap-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.move.wrap-2.2)
|
||
|
||
Otherwise, *movable-box*<T> should store only a T if either T models [movable](concepts.object#concept:movable "18.6 Object concepts [concepts.object]") oris_nothrow_move_constructible_v<T> is true[.](#range.move.wrap-2.2.sentence-1)
|
||
|
||
### [25.7.4](#range.nonprop.cache) Non-propagating cache [[range.nonprop.cache]](range.nonprop.cache)
|
||
|
||
[1](#range.nonprop.cache-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4371)
|
||
|
||
Some types in [range.adaptors] are specified in terms of
|
||
an exposition-only class template *non-propagating-cache*[.](#range.nonprop.cache-1.sentence-1)
|
||
|
||
*non-propagating-cache*<T> behaves exactly like optional<T> with the following differences:
|
||
|
||
- [(1.1)](#range.nonprop.cache-1.1)
|
||
|
||
*non-propagating-cache*<T> constrains its type parameter T with is_object_v<T>.
|
||
|
||
- [(1.2)](#range.nonprop.cache-1.2)
|
||
|
||
The copy constructor is equivalent to:constexpr *non-propagating-cache*(const *non-propagating-cache*&) noexcept {}
|
||
|
||
- [(1.3)](#range.nonprop.cache-1.3)
|
||
|
||
The move constructor is equivalent to:constexpr *non-propagating-cache*(*non-propagating-cache*&& other) noexcept { other.reset();}
|
||
|
||
- [(1.4)](#range.nonprop.cache-1.4)
|
||
|
||
The copy assignment operator is equivalent to:constexpr *non-propagating-cache*& operator=(const *non-propagating-cache*& other) noexcept {if (addressof(other) != this) reset(); return *this;}
|
||
|
||
- [(1.5)](#range.nonprop.cache-1.5)
|
||
|
||
The move assignment operator is equivalent to:constexpr *non-propagating-cache*& operator=(*non-propagating-cache*&& other) noexcept { reset();
|
||
other.reset(); return *this;}
|
||
|
||
- [(1.6)](#range.nonprop.cache-1.6)
|
||
|
||
*non-propagating-cache*<T> has an additional member function template
|
||
specified as follows:
|
||
[ð](#range.nonprop.cache-1.6.itemdecl:1)
|
||
`template<class I>
|
||
constexpr T& emplace-deref(const I& i); // exposition only
|
||
`
|
||
*Mandates*: The declaration T t(*i); is well-formed
|
||
for some invented variable t[.](#range.nonprop.cache-1.6.sentence-2)
|
||
[*Note [1](#range.nonprop.cache-note-1)*:
|
||
If *i is a prvalue of type cv T,
|
||
there is no requirement that it is movable ([[dcl.init.general]](dcl.init.general "9.5.1 General"))[.](#range.nonprop.cache-1.6.sentence-3)
|
||
â *end note*]
|
||
*Effects*: Calls reset()[.](#range.nonprop.cache-1.6.sentence-4)
|
||
Then direct-non-list-initializes the contained value with *i[.](#range.nonprop.cache-1.6.sentence-5)
|
||
*Postconditions*: *this contains a value[.](#range.nonprop.cache-1.6.sentence-6)
|
||
*Returns*: A reference to the new contained value[.](#range.nonprop.cache-1.6.sentence-7)
|
||
*Throws*: Any exception thrown by the initialization of the contained value[.](#range.nonprop.cache-1.6.sentence-8)
|
||
*Remarks*: If an exception is thrown during the initialization of T,*this does not contain a value, and
|
||
the previous value (if any) has been destroyed[.](#range.nonprop.cache-1.6.sentence-9)
|
||
|
||
[2](#range.nonprop.cache-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4449)
|
||
|
||
[*Note [2](#range.nonprop.cache-note-2)*:
|
||
|
||
*non-propagating-cache* enables an input view
|
||
to temporarily cache values as it is iterated over[.](#range.nonprop.cache-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
### [25.7.5](#range.adaptor.helpers) Range adaptor helpers [[range.adaptor.helpers]](range.adaptor.helpers)
|
||
|
||
namespace std::ranges {template<class F, class Tuple>constexpr auto *tuple-transform*(F&& f, Tuple&& t) { // *exposition only*return apply([&]<class... Ts>(Ts&&... elements) {return tuple<invoke_result_t<F&, Ts>...>(invoke(f, std::forward<Ts>(elements))...); }, std::forward<Tuple>(t)); }template<class F, class Tuple>constexpr void *tuple-for-each*(F&& f, Tuple&& t) { // *exposition only* apply([&]<class... Ts>(Ts&&... elements) {(static_cast<void>(invoke(f, std::forward<Ts>(elements))), ...); }, std::forward<Tuple>(t)); }template<class T>constexpr T& *as-lvalue*(T&& t) { // *exposition only*return static_cast<T&>(t); }template<bool Const, class... Views>concept [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]") = // *exposition only*([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Views>> && ...); template<bool Const, class... Views>concept [*all-bidirectional*](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]") = // *exposition only*([bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Views>> && ...); template<bool Const, class... Views>concept [*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]") = // *exposition only*([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Views>> && ...);}
|
||
|
||
### [25.7.6](#range.all) All view [[range.all]](range.all)
|
||
|
||
#### [25.7.6.1](#range.all.general) General [[range.all.general]](range.all.general)
|
||
|
||
[1](#range.all.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4494)
|
||
|
||
views::all returns a view that includes all elements of
|
||
its range argument[.](#range.all.general-1.sentence-1)
|
||
|
||
[2](#range.all.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4499)
|
||
|
||
The name views::all denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.all.general-2.sentence-1)
|
||
|
||
Given a subexpression E, the expressionviews::all(E) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.all.general-2.1)
|
||
|
||
*decay-copy*(E) if the decayed type of E models [view](range.view#concept:view "25.4.5 Views [range.view]")[.](#range.all.general-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.all.general-2.2)
|
||
|
||
Otherwise, ref_view{E} if that expression is well-formed[.](#range.all.general-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.all.general-2.3)
|
||
|
||
Otherwise, owning_view{E}[.](#range.all.general-2.3.sentence-1)
|
||
|
||
#### [25.7.6.2](#range.ref.view) Class template ref_view [[range.ref.view]](range.ref.view)
|
||
|
||
[1](#range.ref.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4515)
|
||
|
||
ref_view is a view of the elements of some other range[.](#range.ref.view-1.sentence-1)
|
||
|
||
[ð](#lib:ref_view)
|
||
|
||
namespace std::ranges {template<[range](range.range#concept:range "25.4.2 Ranges [range.range]") R>requires is_object_v<R>class ref_view : public view_interface<ref_view<R>> {private: R* *r_*; // *exposition only*public:template<[*different-from*](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<ref_view> T>requires *see below*constexpr ref_view(T&& t); constexpr R& base() const { return **r_*; }constexpr iterator_t<R> begin() const { return ranges::begin(**r_*); }constexpr sentinel_t<R> end() const { return ranges::end(**r_*); }constexpr bool empty() constrequires requires { ranges::empty(**r_*); }{ return ranges::empty(**r_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R>{ return ranges::size(**r_*); }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]")<R>{ return ranges::reserve_hint(**r_*); }constexpr auto data() const requires [contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]")<R>{ return ranges::data(**r_*); }}; template<class R> ref_view(R&) -> ref_view<R>;}
|
||
|
||
[ð](#lib:ref_view,constructor)
|
||
|
||
`template<[different-from](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<ref_view> T>
|
||
requires see below
|
||
constexpr ref_view(T&& t);
|
||
`
|
||
|
||
[2](#range.ref.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4563)
|
||
|
||
*Effects*: Initializes *r_* withaddressof(static_cast<R&>(std::forward<T>(t)))[.](#range.ref.view-2.sentence-1)
|
||
|
||
[3](#range.ref.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4568)
|
||
|
||
*Remarks*: Let *FUN* denote the exposition-only functionsvoid *FUN*(R&);void *FUN*(R&&) = delete;
|
||
|
||
The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to:[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<T, R&> && requires { *FUN*(declval<T>()); }
|
||
|
||
#### [25.7.6.3](#range.owning.view) Class template owning_view [[range.owning.view]](range.owning.view)
|
||
|
||
[1](#range.owning.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4583)
|
||
|
||
owning_view is a move-only view
|
||
of the elements of some other range[.](#range.owning.view-1.sentence-1)
|
||
|
||
[ð](#lib:owning_view)
|
||
|
||
namespace std::ranges {template<[range](range.range#concept:range "25.4.2 Ranges [range.range]") R>requires [movable](concepts.object#concept:movable "18.6 Object concepts [concepts.object]")<R> && (!*is-initializer-list*<R>) // see [[range.refinements]](range.refinements "25.4.6 Other range refinements")class owning_view : public view_interface<owning_view<R>> {private: R *r_* = R(); // *exposition only*public: owning_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<R> = default; constexpr owning_view(R&& t);
|
||
|
||
owning_view(owning_view&&) = default;
|
||
owning_view& operator=(owning_view&&) = default; constexpr R& base() & noexcept { return *r_*; }constexpr const R& base() const & noexcept { return *r_*; }constexpr R&& base() && noexcept { return std::move(*r_*); }constexpr const R&& base() const && noexcept { return std::move(*r_*); }constexpr iterator_t<R> begin() { return ranges::begin(*r_*); }constexpr sentinel_t<R> end() { return ranges::end(*r_*); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const R>{ return ranges::begin(*r_*); }constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const R>{ return ranges::end(*r_*); }constexpr bool empty() requires requires { ranges::empty(*r_*); }{ return ranges::empty(*r_*); }constexpr bool empty() const requires requires { ranges::empty(*r_*); }{ return ranges::empty(*r_*); }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R>{ return ranges::size(*r_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const R>{ return ranges::size(*r_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<R>{ return ranges::reserve_hint(*r_*); }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]")<const R>{ return ranges::reserve_hint(*r_*); }constexpr auto data() requires [contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]")<R>{ return ranges::data(*r_*); }constexpr auto data() const requires [contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]")<const R>{ return ranges::data(*r_*); }};}
|
||
|
||
[ð](#lib:owning_view,constructor)
|
||
|
||
`constexpr owning_view(R&& t);
|
||
`
|
||
|
||
[2](#range.owning.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4645)
|
||
|
||
*Effects*: Initializes *r_* with std::move(t)[.](#range.owning.view-2.sentence-1)
|
||
|
||
### [25.7.7](#range.as.rvalue) As rvalue view [[range.as.rvalue]](range.as.rvalue)
|
||
|
||
#### [25.7.7.1](#range.as.rvalue.overview) Overview [[range.as.rvalue.overview]](range.as.rvalue.overview)
|
||
|
||
[1](#range.as.rvalue.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4654)
|
||
|
||
as_rvalue_view presents a view of an underlying sequence
|
||
with the same behavior as the underlying sequence
|
||
except that its elements are rvalues[.](#range.as.rvalue.overview-1.sentence-1)
|
||
|
||
Some generic algorithms can be called with an as_rvalue_view to replace copying with moving[.](#range.as.rvalue.overview-1.sentence-2)
|
||
|
||
[2](#range.as.rvalue.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4661)
|
||
|
||
The name views::as_rvalue denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.as.rvalue.overview-2.sentence-1)
|
||
|
||
Let E be an expression and let T be decltype((E))[.](#range.as.rvalue.overview-2.sentence-2)
|
||
|
||
The expression views::as_rvalue(E) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.as.rvalue.overview-2.1)
|
||
|
||
views::all(E) ifT models [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") and[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<range_rvalue_reference_t<T>, range_reference_t<T>> is true[.](#range.as.rvalue.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.as.rvalue.overview-2.2)
|
||
|
||
Otherwise, as_rvalue_view(E)[.](#range.as.rvalue.overview-2.2.sentence-1)
|
||
|
||
[3](#range.as.rvalue.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4676)
|
||
|
||
[*Example [1](#range.as.rvalue.overview-example-1)*: vector<string> words = {"the", "quick", "brown", "fox", "ate", "a", "pterodactyl"};
|
||
vector<string> new_words;
|
||
ranges::copy(words | views::as_rvalue, back_inserter(new_words)); // moves each string from words into new_words â *end example*]
|
||
|
||
#### [25.7.7.2](#range.as.rvalue.view) Class template as_rvalue_view [[range.as.rvalue.view]](range.as.rvalue.view)
|
||
|
||
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]")<V>class [as_rvalue_view](#lib:as_rvalue_view "25.7.7.2 Class template as_rvalue_view [range.as.rvalue.view]") : public view_interface<as_rvalue_view<V>> { V *base_* = V(); // *exposition only*public: as_rvalue_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit as_rvalue_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>){ return move_iterator(ranges::begin(*base_*)); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>{ return move_iterator(ranges::begin(*base_*)); }constexpr auto end() requires (<V>) {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>) {return move_iterator(ranges::end(*base_*)); } else {return move_sentinel(ranges::end(*base_*)); }}constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>) {return move_iterator(ranges::end(*base_*)); } else {return move_sentinel(ranges::end(*base_*)); }}constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> { return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> { return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>{ return ranges::reserve_hint(*base_*); }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]")<const V>{ return ranges::reserve_hint(*base_*); }}; template<class R> as_rvalue_view(R&&) -> as_rvalue_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:as_rvalue_view,constructor)
|
||
|
||
`constexpr explicit as_rvalue_view(V base);
|
||
`
|
||
|
||
[1](#range.as.rvalue.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4742)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.as.rvalue.view-1.sentence-1)
|
||
|
||
### [25.7.8](#range.filter) Filter view [[range.filter]](range.filter)
|
||
|
||
#### [25.7.8.1](#range.filter.overview) Overview [[range.filter.overview]](range.filter.overview)
|
||
|
||
[1](#range.filter.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4751)
|
||
|
||
filter_view presents a view of the elements
|
||
of an underlying sequence that satisfy a predicate[.](#range.filter.overview-1.sentence-1)
|
||
|
||
[2](#range.filter.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4755)
|
||
|
||
The name views::filter denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.filter.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and P,
|
||
the expression views::filter(E, P) is expression-equivalent tofilter_view(E, P)[.](#range.filter.overview-2.sentence-2)
|
||
|
||
[3](#range.filter.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4763)
|
||
|
||
[*Example [1](#range.filter.overview-example-1)*: vector<int> is{ 0, 1, 2, 3, 4, 5, 6 };auto evens = views::filter(is, [](int i) { return 0 == i % 2; });for (int i : evens) cout << i << ' '; // prints 0 2 4 6 â *end example*]
|
||
|
||
#### [25.7.8.2](#range.filter.view) Class template filter_view [[range.filter.view]](range.filter.view)
|
||
|
||
[ð](#lib:filter_view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<iterator_t<V>> Pred>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<Pred>class filter_view : public view_interface<filter_view<V, Pred>> {private: V *base_* = V(); // *exposition only**movable-box*<Pred> *pred_*; // *exposition only*// [[range.filter.iterator]](#range.filter.iterator "25.7.8.3 Class filter_view::iterator"), class filter_view::*iterator*class *iterator*; // *exposition only*// [[range.filter.sentinel]](#range.filter.sentinel "25.7.8.4 Class filter_view::sentinel"), class filter_view::*sentinel*class *sentinel*; // *exposition only*public: filter_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pred> = default; constexpr explicit filter_view(V base, Pred pred); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr const Pred& pred() const; constexpr *iterator* begin(); constexpr auto end() {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>)return *iterator*{*this, ranges::end(*base_*)}; elsereturn *sentinel*{*this}; }}; template<class R, class Pred> filter_view(R&&, Pred) -> filter_view<views::all_t<R>, Pred>;}
|
||
|
||
[ð](#lib:filter_view,constructor)
|
||
|
||
`constexpr explicit filter_view(V base, Pred pred);
|
||
`
|
||
|
||
[1](#range.filter.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4822)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and initializes*pred_* with std::move(pred)[.](#range.filter.view-1.sentence-1)
|
||
|
||
[ð](#lib:pred,filter_view)
|
||
|
||
`constexpr const Pred& pred() const;
|
||
`
|
||
|
||
[2](#range.filter.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4834)
|
||
|
||
*Effects*: Equivalent to: return **pred_*;
|
||
|
||
[ð](#lib:begin,filter_view)
|
||
|
||
`constexpr iterator begin();
|
||
`
|
||
|
||
[3](#range.filter.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4845)
|
||
|
||
*Preconditions*: *pred_*.has_value() is true[.](#range.filter.view-3.sentence-1)
|
||
|
||
[4](#range.filter.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4849)
|
||
|
||
*Returns*: {*this, ranges::find_if(*base_*, ref(**pred_*))}[.](#range.filter.view-4.sentence-1)
|
||
|
||
[5](#range.filter.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4853)
|
||
|
||
*Remarks*: In order to provide the amortized constant time complexity required by
|
||
the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept
|
||
when filter_view models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
this function caches the result within thefilter_view for use on subsequent calls[.](#range.filter.view-5.sentence-1)
|
||
|
||
#### [25.7.8.3](#range.filter.iterator) Class filter_view::*iterator* [[range.filter.iterator]](range.filter.iterator)
|
||
|
||
[ð](#lib:filter_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<iterator_t<V>> Pred>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<Pred>class filter_view<V, Pred>::*iterator* {private: iterator_t<V> *current_* = iterator_t<V>(); // *exposition only* filter_view* *parent_* = nullptr; // *exposition only*public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = range_value_t<V>; using difference_type = range_difference_t<V>; *iterator*() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iterator_t<V>> = default; constexpr *iterator*(filter_view& parent, iterator_t<V> current); constexpr const iterator_t<V>& base() const & noexcept; constexpr iterator_t<V> base() &&; constexpr range_reference_t<V> operator*() const; constexpr iterator_t<V> operator->() constrequires [*has-arrow*](range.utility.helpers#concept:has-arrow "25.5.2 Helper concepts [range.utility.helpers]")<iterator_t<V>> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<iterator_t<V>>; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>; constexpr *iterator*& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>; constexpr *iterator* operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<V>>; friend constexpr range_rvalue_reference_t<V> iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(i.*current_*))); friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)noexcept(noexcept(ranges::iter_swap(x.*current_*, y.*current_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<V>>; };}
|
||
|
||
[1](#range.filter.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4910)
|
||
|
||
Modification of the element a filter_view::*iterator* denotes is
|
||
permitted, but results in undefined behavior if the resulting value does not
|
||
satisfy the filter predicate[.](#range.filter.iterator-1.sentence-1)
|
||
|
||
[2](#range.filter.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4915)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(2.1)](#range.filter.iterator-2.1)
|
||
|
||
If V models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"), theniterator_concept denotes bidirectional_iterator_tag[.](#range.filter.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.filter.iterator-2.2)
|
||
|
||
Otherwise, if V models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"), theniterator_concept denotes forward_iterator_tag[.](#range.filter.iterator-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.filter.iterator-2.3)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.filter.iterator-2.3.sentence-1)
|
||
|
||
[3](#range.filter.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4927)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if V models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.filter.iterator-3.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
|
||
- [(3.1)](#range.filter.iterator-3.1)
|
||
|
||
Let C denote the typeiterator_traits<iterator_t<V>>::iterator_category[.](#range.filter.iterator-3.1.sentence-1)
|
||
|
||
- [(3.2)](#range.filter.iterator-3.2)
|
||
|
||
If C models[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<bidirectional_iterator_tag>,
|
||
then iterator_category denotes bidirectional_iterator_tag[.](#range.filter.iterator-3.2.sentence-1)
|
||
|
||
- [(3.3)](#range.filter.iterator-3.3)
|
||
|
||
Otherwise, if C models[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<forward_iterator_tag>,
|
||
then iterator_category denotes forward_iterator_tag[.](#range.filter.iterator-3.3.sentence-1)
|
||
|
||
- [(3.4)](#range.filter.iterator-3.4)
|
||
|
||
Otherwise, iterator_category denotes C[.](#range.filter.iterator-3.4.sentence-1)
|
||
|
||
[ð](#lib:filter_view::iterator,constructor)
|
||
|
||
`constexpr iterator(filter_view& parent, iterator_t<V> current);
|
||
`
|
||
|
||
[4](#range.filter.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4953)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current) and*parent_* with addressof(parent)[.](#range.filter.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:base,filter_view::iterator)
|
||
|
||
`constexpr const iterator_t<V>& base() const & noexcept;
|
||
`
|
||
|
||
[5](#range.filter.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4965)
|
||
|
||
*Effects*: Equivalent to: return *current_*;
|
||
|
||
[ð](#lib:base,filter_view::iterator_)
|
||
|
||
`constexpr iterator_t<V> base() &&;
|
||
`
|
||
|
||
[6](#range.filter.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4976)
|
||
|
||
*Effects*: Equivalent to: return std::move(*current_*);
|
||
|
||
[ð](#lib:operator*,filter_view::iterator)
|
||
|
||
`constexpr range_reference_t<V> operator*() const;
|
||
`
|
||
|
||
[7](#range.filter.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4987)
|
||
|
||
*Effects*: Equivalent to: return **current_*;
|
||
|
||
[ð](#lib:operator-%3e,filter_view::iterator)
|
||
|
||
`constexpr iterator_t<V> operator->() const
|
||
requires [has-arrow](range.utility.helpers#concept:has-arrow "25.5.2 Helper concepts [range.utility.helpers]")<iterator_t<V>> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<iterator_t<V>>;
|
||
`
|
||
|
||
[8](#range.filter.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L4999)
|
||
|
||
*Effects*: Equivalent to: return *current_*;
|
||
|
||
[ð](#lib:operator++,filter_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[9](#range.filter.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5010)
|
||
|
||
*Effects*: Equivalent to:*current_* = ranges::find_if(std::move(++*current_*), ranges::end(*parent_*->*base_*),
|
||
ref(**parent_*->*pred_*));return *this;
|
||
|
||
[ð](#lib:operator++,filter_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[10](#range.filter.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5026)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.filter.iterator-10.sentence-1)
|
||
|
||
[ð](#lib:operator++,filter_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[11](#range.filter.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5037)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,filter_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[12](#range.filter.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5053)
|
||
|
||
*Effects*: Equivalent to:do--*current_*;while (!invoke(**parent_*->*pred_*, **current_*));return *this;
|
||
|
||
[ð](#lib:operator--,filter_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[13](#range.filter.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5070)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator==,filter_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<V>>;
|
||
`
|
||
|
||
[14](#range.filter.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5087)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*current_*;
|
||
|
||
[ð](#lib:iter_move,filter_view::iterator)
|
||
|
||
`friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
|
||
noexcept(noexcept(ranges::iter_move(i.current_)));
|
||
`
|
||
|
||
[15](#range.filter.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5099)
|
||
|
||
*Effects*: Equivalent to: return ranges::iter_move(i.*current_*);
|
||
|
||
[ð](#lib:iter_swap,filter_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
||
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<V>>;
|
||
`
|
||
|
||
[16](#range.filter.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5112)
|
||
|
||
*Effects*: Equivalent to ranges::iter_swap(x.*current_*, y.*current_*)[.](#range.filter.iterator-16.sentence-1)
|
||
|
||
#### [25.7.8.4](#range.filter.sentinel) Class filter_view::*sentinel* [[range.filter.sentinel]](range.filter.sentinel)
|
||
|
||
[ð](#lib:filter_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<iterator_t<V>> Pred>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<Pred>class filter_view<V, Pred>::*sentinel* {private: sentinel_t<V> *end_* = sentinel_t<V>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(filter_view& parent); constexpr sentinel_t<V> base() const; friend constexpr bool operator==(const *iterator*& x, const *sentinel*& y); };}
|
||
|
||
[ð](#lib:filter_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(filter_view& parent);
|
||
`
|
||
|
||
[1](#range.filter.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5146)
|
||
|
||
*Effects*: Initializes *end_* with ranges::end(parent.*base_*)[.](#range.filter.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:base,filter_view::sentinel)
|
||
|
||
`constexpr sentinel_t<V> base() const;
|
||
`
|
||
|
||
[2](#range.filter.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5157)
|
||
|
||
*Effects*: Equivalent to: return *end_*;
|
||
|
||
[ð](#lib:operator==,filter_view::sentinel)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.filter.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5168)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*end_*;
|
||
|
||
### [25.7.9](#range.transform) Transform view [[range.transform]](range.transform)
|
||
|
||
#### [25.7.9.1](#range.transform.overview) Overview [[range.transform.overview]](range.transform.overview)
|
||
|
||
[1](#range.transform.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5177)
|
||
|
||
transform_view presents
|
||
a view of an underlying sequence after
|
||
applying a transformation function to each element[.](#range.transform.overview-1.sentence-1)
|
||
|
||
[2](#range.transform.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5182)
|
||
|
||
The name views::transform denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.transform.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F, the expressionviews::transform(E, F) is expression-equivalent totransform_view(E, F)[.](#range.transform.overview-2.sentence-2)
|
||
|
||
[3](#range.transform.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5190)
|
||
|
||
[*Example [1](#range.transform.overview-example-1)*: vector<int> is{ 0, 1, 2, 3, 4 };auto squares = views::transform(is, [](int i) { return i * i; });for (int i : squares) cout << i << ' '; // prints 0 1 4 9 16 â *end example*]
|
||
|
||
#### [25.7.9.2](#range.transform.view) Class template transform_view [[range.transform.view]](range.transform.view)
|
||
|
||
[ð](#lib:transform_view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, range_reference_t<V>> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, range_reference_t<V>>>class transform_view : public view_interface<transform_view<V, F>> {private:// [[range.transform.iterator]](#range.transform.iterator "25.7.9.3 Class template transform_view::iterator"), class template transform_view::*iterator*template<bool> struct *iterator*; // *exposition only*// [[range.transform.sentinel]](#range.transform.sentinel "25.7.9.4 Class template transform_view::sentinel"), class template transform_view::*sentinel*template<bool> struct *sentinel*; // *exposition only* V *base_* = V(); // *exposition only**movable-box*<F> *fun_*; // *exposition only*public: transform_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<F> = default; constexpr explicit transform_view(V base, F fun); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr *iterator*<false> begin(); constexpr *iterator*<true> begin() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const V>>; constexpr *sentinel*<false> end(); constexpr *iterator*<false> end() requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>; constexpr *sentinel*<true> end() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const V>>; constexpr *iterator*<true> end() constrequires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const V>>; constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> { return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>{ return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>{ return ranges::reserve_hint(*base_*); }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]")<const V>{ return ranges::reserve_hint(*base_*); }}; template<class R, class F> transform_view(R&&, F) -> transform_view<views::all_t<R>, F>;}
|
||
|
||
[ð](#lib:transform_view,constructor)
|
||
|
||
`constexpr explicit transform_view(V base, F fun);
|
||
`
|
||
|
||
[1](#range.transform.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5264)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*fun_* with std::move(fun)[.](#range.transform.view-1.sentence-1)
|
||
|
||
[ð](#lib:begin,transform_view)
|
||
|
||
`constexpr iterator<false> begin();
|
||
`
|
||
|
||
[2](#range.transform.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5276)
|
||
|
||
*Effects*: Equivalent to:return *iterator*<false>{*this, ranges::begin(*base_*)};
|
||
|
||
[ð](#lib:begin,transform_view_)
|
||
|
||
`constexpr iterator<true> begin() const
|
||
requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> &&
|
||
[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const V>>;
|
||
`
|
||
|
||
[3](#range.transform.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5292)
|
||
|
||
*Effects*: Equivalent to:return *iterator*<true>{*this, ranges::begin(*base_*)};
|
||
|
||
[ð](#lib:end,transform_view)
|
||
|
||
`constexpr sentinel<false> end();
|
||
`
|
||
|
||
[4](#range.transform.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5306)
|
||
|
||
*Effects*: Equivalent to:return *sentinel*<false>{ranges::end(*base_*)};
|
||
|
||
[ð](#lib:end,transform_view_)
|
||
|
||
`constexpr iterator<false> end() requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[5](#range.transform.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5320)
|
||
|
||
*Effects*: Equivalent to:return *iterator*<false>{*this, ranges::end(*base_*)};
|
||
|
||
[ð](#lib:end,transform_view__)
|
||
|
||
`constexpr sentinel<true> end() const
|
||
requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> &&
|
||
[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const V>>;
|
||
`
|
||
|
||
[6](#range.transform.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5336)
|
||
|
||
*Effects*: Equivalent to:return *sentinel*<true>{ranges::end(*base_*)};
|
||
|
||
[ð](#lib:end,transform_view___)
|
||
|
||
`constexpr iterator<true> end() const
|
||
requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> &&
|
||
[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const V>>;
|
||
`
|
||
|
||
[7](#range.transform.view-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5352)
|
||
|
||
*Effects*: Equivalent to:return *iterator*<true>{*this, ranges::end(*base_*)};
|
||
|
||
#### [25.7.9.3](#range.transform.iterator) Class template transform_view::*iterator* [[range.transform.iterator]](range.transform.iterator)
|
||
|
||
[ð](#lib:transform_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, range_reference_t<V>> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, range_reference_t<V>>>template<bool Const>class transform_view<V, F>::*iterator* {private:using *Parent* = *maybe-const*<Const, transform_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only**Parent** *parent_* = nullptr; // *exposition only*public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = remove_cvref_t<invoke_result_t<*maybe-const*<Const, F>&, range_reference_t<*Base*>>>; using difference_type = range_difference_t<*Base*>; *iterator*() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iterator_t<*Base*>> = default; constexpr *iterator*(*Parent*& parent, iterator_t<*Base*> current); constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr const iterator_t<*Base*>& base() const & noexcept; constexpr iterator_t<*Base*> base() &&; constexpr decltype(auto) operator*() constnoexcept(noexcept(invoke(**parent_*->*fun_*, **current_*))) {return invoke(**parent_*->*fun_*, **current_*); }constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; 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 n)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr *iterator*& operator-=(difference_type n)requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr decltype(auto) operator[](difference_type n) constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*> {return invoke(**parent_*->*fun_*, *current_*[n]); }friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<*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 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]")<iterator_t<*Base*>>; friend constexpr *iterator* operator+(*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, *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-(*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*>, iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.transform.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5441)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.transform.iterator-1.1)
|
||
|
||
If *Base* models [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]"), theniterator_concept denotes random_access_iterator_tag[.](#range.transform.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.transform.iterator-1.2)
|
||
|
||
Otherwise, if *Base* models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"), theniterator_concept denotes bidirectional_iterator_tag[.](#range.transform.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.transform.iterator-1.3)
|
||
|
||
Otherwise, if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"), theniterator_concept denotes forward_iterator_tag[.](#range.transform.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.transform.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.transform.iterator-1.4.sentence-1)
|
||
|
||
[2](#range.transform.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5456)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.transform.iterator-2.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
Let C denote the typeiterator_traits<iterator_t<*Base*>>::iterator_category[.](#range.transform.iterator-2.sentence-2)
|
||
|
||
- [(2.1)](#range.transform.iterator-2.1)
|
||
|
||
If is_reference_v<invoke_result_t<*maybe-const*<Const, F>&, range_reference_t<*Base*>>> is true, then
|
||
* [(2.1.1)](#range.transform.iterator-2.1.1)
|
||
|
||
if C models [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<contiguous_iterator_tag>,iterator_category denotes random_access_iterator_tag;
|
||
|
||
* [(2.1.2)](#range.transform.iterator-2.1.2)
|
||
|
||
otherwise,iterator_category denotes C[.](#range.transform.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.transform.iterator-2.2)
|
||
|
||
Otherwise, iterator_category denotes input_iterator_tag[.](#range.transform.iterator-2.2.sentence-1)
|
||
|
||
[ð](#lib:iterator,transform_view::iterator)
|
||
|
||
`constexpr iterator(Parent& parent, iterator_t<Base> current);
|
||
`
|
||
|
||
[3](#range.transform.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5487)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current) and*parent_* with addressof(parent)[.](#range.transform.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:transform_view::iterator,constructor)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[4](#range.transform.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5500)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*) and*parent_* with i.*parent_*[.](#range.transform.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:base,transform_view::iterator)
|
||
|
||
`constexpr const iterator_t<Base>& base() const & noexcept;
|
||
`
|
||
|
||
[5](#range.transform.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5512)
|
||
|
||
*Effects*: Equivalent to: return *current_*;
|
||
|
||
[ð](#lib:base,transform_view::iterator_)
|
||
|
||
`constexpr iterator_t<Base> base() &&;
|
||
`
|
||
|
||
[6](#range.transform.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5523)
|
||
|
||
*Effects*: Equivalent to: return std::move(*current_*);
|
||
|
||
[ð](#lib:operator++,transform_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.transform.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5534)
|
||
|
||
*Effects*: Equivalent to:++*current_*;return *this;
|
||
|
||
[ð](#lib:operator++,transform_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[8](#range.transform.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5549)
|
||
|
||
*Effects*: Equivalent to ++*current_*[.](#range.transform.iterator-8.sentence-1)
|
||
|
||
[ð](#lib:operator++,transform_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[9](#range.transform.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5560)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,transform_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[10](#range.transform.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5576)
|
||
|
||
*Effects*: Equivalent to:--*current_*;return *this;
|
||
|
||
[ð](#lib:operator--,transform_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[11](#range.transform.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5591)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,transform_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[12](#range.transform.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5608)
|
||
|
||
*Effects*: Equivalent to:*current_* += n;return *this;
|
||
|
||
[ð](#lib:operator-=,transform_view::iterator)
|
||
|
||
`constexpr iterator& operator-=(difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[13](#range.transform.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5624)
|
||
|
||
*Effects*: Equivalent to:*current_* -= n;return *this;
|
||
|
||
[ð](#lib:operator==,transform_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[14](#range.transform.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5640)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*current_*;
|
||
|
||
[ð](#lib:operator%3c,transform_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]")<Base>;
|
||
`
|
||
|
||
[15](#range.transform.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5652)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* < y.*current_*;
|
||
|
||
[ð](#lib:operator%3e,transform_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]")<Base>;
|
||
`
|
||
|
||
[16](#range.transform.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5664)
|
||
|
||
*Effects*: Equivalent to: return y < x;
|
||
|
||
[ð](#lib:operator%3c=,transform_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]")<Base>;
|
||
`
|
||
|
||
[17](#range.transform.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5676)
|
||
|
||
*Effects*: Equivalent to: return !(y < x);
|
||
|
||
[ð](#lib:operator%3e=,transform_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]")<Base>;
|
||
`
|
||
|
||
[18](#range.transform.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5688)
|
||
|
||
*Effects*: Equivalent to: return !(x < y);
|
||
|
||
[ð](#lib:operator%3c=%3e,transform_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]")<Base> && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[19](#range.transform.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5700)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* <=> y.*current_*;
|
||
|
||
[ð](#lib:operator+,transform_view::iterator)
|
||
|
||
`friend constexpr iterator operator+(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, iterator i)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[20](#range.transform.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5714)
|
||
|
||
*Effects*: Equivalent to: return *iterator*{*i.*parent_*, i.*current_* + n};
|
||
|
||
[ð](#lib:operator-,transform_view::iterator)
|
||
|
||
`friend constexpr iterator operator-(iterator i, difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[21](#range.transform.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5726)
|
||
|
||
*Effects*: Equivalent to: return *iterator*{*i.*parent_*, i.*current_* - n};
|
||
|
||
[ð](#lib:operator-,transform_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<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[22](#range.transform.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5738)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* - y.*current_*;
|
||
|
||
#### [25.7.9.4](#range.transform.sentinel) Class template transform_view::*sentinel* [[range.transform.sentinel]](range.transform.sentinel)
|
||
|
||
[ð](#lib:transform_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, range_reference_t<V>> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, range_reference_t<V>>>template<bool Const>class transform_view<V, F>::*sentinel* {private:using *Parent* = *maybe-const*<Const, transform_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(sentinel_t<*Base*> end); constexpr *sentinel*(*sentinel*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; constexpr sentinel_t<*Base*> base() const; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *sentinel*& y, const *iterator*<OtherConst>& x); };}
|
||
|
||
[ð](#lib:transform_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<Base> end);
|
||
`
|
||
|
||
[1](#range.transform.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5791)
|
||
|
||
*Effects*: Initializes *end_* with end[.](#range.transform.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:transform_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.transform.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5803)
|
||
|
||
*Effects*: Initializes *end_* with std::move(i.*end_*)[.](#range.transform.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:base,transform_view::sentinel)
|
||
|
||
`constexpr sentinel_t<Base> base() const;
|
||
`
|
||
|
||
[3](#range.transform.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5814)
|
||
|
||
*Effects*: Equivalent to: return *end_*;
|
||
|
||
[ð](#lib:operator==,transform_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[4](#range.transform.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5827)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*end_*;
|
||
|
||
[ð](#lib:operator-,transform_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[5](#range.transform.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5841)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* - y.*end_*;
|
||
|
||
[ð](#lib:operator-,transform_view::sentinel_)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
||
`
|
||
|
||
[6](#range.transform.sentinel-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5855)
|
||
|
||
*Effects*: Equivalent to: return y.*end_* - x.*current_*;
|
||
|
||
### [25.7.10](#range.take) Take view [[range.take]](range.take)
|
||
|
||
#### [25.7.10.1](#range.take.overview) Overview [[range.take.overview]](range.take.overview)
|
||
|
||
[1](#range.take.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5864)
|
||
|
||
take_view produces a view of the first N elements
|
||
from another view, or all the elements if the adapted
|
||
view contains fewer than N[.](#range.take.overview-1.sentence-1)
|
||
|
||
[2](#range.take.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5869)
|
||
|
||
The name views::take denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.take.overview-2.sentence-1)
|
||
|
||
Let E and F be expressions,
|
||
let T be remove_cvref_t<decltype((E))>, and
|
||
let D be range_difference_t<decltype((E))>[.](#range.take.overview-2.sentence-2)
|
||
|
||
If decltype((F)) does not model[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<D>,views::take(E, F) is ill-formed[.](#range.take.overview-2.sentence-3)
|
||
|
||
Otherwise, the expression views::take(E, F) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.take.overview-2.1)
|
||
|
||
If T is a specialization
|
||
of empty_view ([[range.empty.view]](range.empty.view "25.6.2.2 Class template empty_view")),
|
||
then ((void)F, *decay-copy*(E)),
|
||
except that the evaluations of E and F are indeterminately sequenced[.](#range.take.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.take.overview-2.2)
|
||
|
||
Otherwise, if T models[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") and [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") and is a specialization ofspan ([[views.span]](views.span "23.7.2.2 Class template span")),basic_string_view ([[string.view]](string.view "27.3 String view classes")), orsubrange ([[range.subrange]](range.subrange "25.5.4 Sub-ranges")),
|
||
thenU(ranges::begin(E),
|
||
ranges::begin(E) + std::min<D>(ranges::distance(E), F)),
|
||
except that E is evaluated only once,
|
||
where U is a type determined as follows:
|
||
* [(2.2.1)](#range.take.overview-2.2.1)
|
||
|
||
if T is a specialization of span,
|
||
then U is span<typename T::element_type>;
|
||
|
||
* [(2.2.2)](#range.take.overview-2.2.2)
|
||
|
||
otherwise, if T is a specialization of basic_string_view,
|
||
then U is T;
|
||
|
||
* [(2.2.3)](#range.take.overview-2.2.3)
|
||
|
||
otherwise, T is a specialization of subrange, andU is subrange<iterator_t<T>>;
|
||
|
||
- [(2.3)](#range.take.overview-2.3)
|
||
|
||
otherwise, if T is
|
||
a specialization of iota_view ([[range.iota.view]](range.iota.view "25.6.4.2 Class template iota_view"))
|
||
that models [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") and [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"),
|
||
theniota_view(*ranges::begin(E),*(ranges::begin(E) + std::min<D>(ranges::distance(E), F))),
|
||
except that E is evaluated only once[.](#range.take.overview-2.3.sentence-1)
|
||
|
||
- [(2.4)](#range.take.overview-2.4)
|
||
|
||
Otherwise, if T is
|
||
a specialization of repeat_view ([[range.repeat.view]](range.repeat.view "25.6.5.2 Class template repeat_view")):
|
||
* [(2.4.1)](#range.take.overview-2.4.1)
|
||
|
||
if T models [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"),
|
||
thenviews::repeat(*E.*value_*, std::min<D>(ranges::distance(E), F)) except that E is evaluated only once;
|
||
|
||
* [(2.4.2)](#range.take.overview-2.4.2)
|
||
|
||
otherwise, views::repeat(*E.*value_*, static_cast<D>(F))[.](#range.take.overview-2.4.sentence-1)
|
||
|
||
- [(2.5)](#range.take.overview-2.5)
|
||
|
||
Otherwise, take_view(E, F)[.](#range.take.overview-2.5.sentence-1)
|
||
|
||
[3](#range.take.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L5938)
|
||
|
||
[*Example [1](#range.take.overview-example-1)*: vector<int> is{0,1,2,3,4,5,6,7,8,9};for (int i : is | views::take(5)) cout << i << ' '; // prints 0 1 2 3 4 â *end example*]
|
||
|
||
#### [25.7.10.2](#range.take.view) Class template take_view [[range.take.view]](range.take.view)
|
||
|
||
[ð](#lib:take_view)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>class take_view : public view_interface<take_view<V>> {private: V *base_* = V(); // *exposition only* range_difference_t<V> *count_* = 0; // *exposition only*// [[range.take.sentinel]](#range.take.sentinel "25.7.10.3 Class template take_view::sentinel"), class template take_view::*sentinel*template<bool> class *sentinel*; // *exposition only*public: take_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit take_view(V base, range_difference_t<V> count); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>) {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>) {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<V>) {return ranges::begin(*base_*); } else {auto sz = range_difference_t<V>(size()); return counted_iterator(ranges::begin(*base_*), sz); }} else if constexpr ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>) {auto it = ranges::begin(*base_*); auto sz = std::min(*count_*, ranges::end(*base_*) - it); return counted_iterator(std::move(it), sz); } else {return counted_iterator(ranges::begin(*base_*), *count_*); }}constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>) {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V>) {return ranges::begin(*base_*); } else {auto sz = range_difference_t<const V>(size()); return counted_iterator(ranges::begin(*base_*), sz); }} else if constexpr ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<const V>, iterator_t<const V>>) {auto it = ranges::begin(*base_*); auto sz = std::min(*count_*, ranges::end(*base_*) - it); return counted_iterator(std::move(it), sz); } else {return counted_iterator(ranges::begin(*base_*), *count_*); }}constexpr auto end() requires (<V>) {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>) {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<V>)return ranges::begin(*base_*) + range_difference_t<V>(size()); elsereturn default_sentinel; } else if constexpr ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>) {return default_sentinel; } else {return *sentinel*<false>{ranges::end(*base_*)}; }}constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>) {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V>)return ranges::begin(*base_*) + range_difference_t<const V>(size()); elsereturn default_sentinel; } else if constexpr ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<const V>, iterator_t<const V>>) {return default_sentinel; } else {return *sentinel*<true>{ranges::end(*base_*)}; }}constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> {auto n = ranges::size(*base_*); return ranges::min(n, static_cast<decltype(n)>(*count_*)); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> {auto n = ranges::size(*base_*); return ranges::min(n, static_cast<decltype(n)>(*count_*)); }constexpr auto reserve_hint() {if constexpr ([approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>) {auto n = static_cast<range_difference_t<V>>(ranges::reserve_hint(*base_*)); return *to-unsigned-like*(ranges::min(n, *count_*)); }return *to-unsigned-like*(*count_*); }constexpr auto reserve_hint() const {if constexpr ([approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<const V>) {auto n = static_cast<range_difference_t<const V>>(ranges::reserve_hint(*base_*)); return *to-unsigned-like*(ranges::min(n, *count_*)); }return *to-unsigned-like*(*count_*); }}; template<class R> take_view(R&&, range_difference_t<R>)-> take_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:take_view,constructor)
|
||
|
||
`constexpr explicit take_view(V base, range_difference_t<V> count);
|
||
`
|
||
|
||
[1](#range.take.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6071)
|
||
|
||
*Preconditions*: count >= 0 is true[.](#range.take.view-1.sentence-1)
|
||
|
||
[2](#range.take.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6075)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*count_* with count[.](#range.take.view-2.sentence-1)
|
||
|
||
#### [25.7.10.3](#range.take.sentinel) Class template take_view::*sentinel* [[range.take.sentinel]](range.take.sentinel)
|
||
|
||
[ð](#lib:take_view::sentinel)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>template<bool Const>class take_view<V>::*sentinel* {private:using *Base* = *maybe-const*<Const, V>; // *exposition only*template<bool OtherConst>using *CI* = counted_iterator<iterator_t<*maybe-const*<OtherConst, V>>>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(sentinel_t<*Base*> end); constexpr *sentinel*(*sentinel*<!Const> s)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; constexpr sentinel_t<*Base*> base() const; friend constexpr bool operator==(const *CI*<Const>& y, const *sentinel*& x); template<bool OtherConst = !Const>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *CI*<OtherConst>& y, const *sentinel*& x); };}
|
||
|
||
[ð](#lib:take_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<Base> end);
|
||
`
|
||
|
||
[1](#range.take.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6118)
|
||
|
||
*Effects*: Initializes *end_* with end[.](#range.take.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:take_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> s)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.take.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6130)
|
||
|
||
*Effects*: Initializes *end_* with std::move(s.*end_*)[.](#range.take.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:base,take_view::sentinel)
|
||
|
||
`constexpr sentinel_t<Base> base() const;
|
||
`
|
||
|
||
[3](#range.take.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6141)
|
||
|
||
*Effects*: Equivalent to: return *end_*;
|
||
|
||
[ð](#lib:operator==,take_view::sentinel)
|
||
|
||
`friend constexpr bool operator==(const CI<Const>& y, const sentinel& x);
|
||
|
||
template<bool OtherConst = !Const>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);
|
||
`
|
||
|
||
[4](#range.take.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6156)
|
||
|
||
*Effects*: Equivalent to:return y.count() == 0 || y.base() == x.*end_*;
|
||
|
||
### [25.7.11](#range.take.while) Take while view [[range.take.while]](range.take.while)
|
||
|
||
#### [25.7.11.1](#range.take.while.overview) Overview [[range.take.while.overview]](range.take.while.overview)
|
||
|
||
[1](#range.take.while.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6166)
|
||
|
||
Given a unary predicate pred and a view r,take_while_view produces a view
|
||
of the range [ranges::begin(r), ranges::find_if_not(r, pred))[.](#range.take.while.overview-1.sentence-1)
|
||
|
||
[2](#range.take.while.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6172)
|
||
|
||
The name views::take_while denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.take.while.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F,
|
||
the expression views::take_while(E, F) is expression-equivalent to take_while_view(E, F)[.](#range.take.while.overview-2.sentence-2)
|
||
|
||
[3](#range.take.while.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6180)
|
||
|
||
[*Example [1](#range.take.while.overview-example-1)*: auto input = istringstream{"0 1 2 3 4 5 6 7 8 9"};auto small = [](const auto x) noexcept { return x < 5; };auto small_ints = views::istream<int>(input) | views::take_while(small);for (const auto i : small_ints) { cout << i << ' '; // prints 0 1 2 3 4}auto i = 0;
|
||
input >> i;
|
||
cout << i; // prints 6 â *end example*]
|
||
|
||
#### [25.7.11.2](#range.take.while.view) Class template take_while_view [[range.take.while.view]](range.take.while.view)
|
||
|
||
[ð](#lib:take_while_view)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V, class Pred>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<V> && is_object_v<Pred> &&[indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<const Pred, iterator_t<V>>class take_while_view : public view_interface<take_while_view<V, Pred>> {// [[range.take.while.sentinel]](#range.take.while.sentinel "25.7.11.3 Class template take_while_view::sentinel"), class template take_while_view::*sentinel*template<bool> class *sentinel*; // *exposition only* V *base_* = V(); // *exposition only**movable-box*<Pred> *pred_*; // *exposition only*public: take_while_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pred> = default; constexpr explicit take_while_view(V base, Pred pred); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr const Pred& pred() const; constexpr auto begin() requires (<V>){ return ranges::begin(*base_*); }constexpr auto begin() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> &&[indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<const Pred, iterator_t<const V>>{ return ranges::begin(*base_*); }constexpr auto end() requires (<V>){ return *sentinel*<false>(ranges::end(*base_*), addressof(**pred_*)); }constexpr auto end() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> &&[indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<const Pred, iterator_t<const V>>{ return *sentinel*<true>(ranges::end(*base_*), addressof(**pred_*)); }}; template<class R, class Pred> take_while_view(R&&, Pred) -> take_while_view<views::all_t<R>, Pred>;}
|
||
|
||
[ð](#lib:take_while_view,constructor)
|
||
|
||
`constexpr explicit take_while_view(V base, Pred pred);
|
||
`
|
||
|
||
[1](#range.take.while.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6250)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*pred_* with std::move(pred)[.](#range.take.while.view-1.sentence-1)
|
||
|
||
[ð](#lib:pred,take_while_view)
|
||
|
||
`constexpr const Pred& pred() const;
|
||
`
|
||
|
||
[2](#range.take.while.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6262)
|
||
|
||
*Effects*: Equivalent to: return **pred_*;
|
||
|
||
#### [25.7.11.3](#range.take.while.sentinel) Class template take_while_view::*sentinel* [[range.take.while.sentinel]](range.take.while.sentinel)
|
||
|
||
[ð](#lib:take_while_view::sentinel)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V, class Pred>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<V> && is_object_v<Pred> &&[indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<const Pred, iterator_t<V>>template<bool Const>class take_while_view<V, Pred>::*sentinel* {using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*const Pred* *pred_* = nullptr; // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(sentinel_t<*Base*> end, const Pred* pred); constexpr *sentinel*(*sentinel*<!Const> s)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; constexpr sentinel_t<*Base*> base() const { return *end_*; }friend constexpr bool operator==(const iterator_t<*Base*>& x, const *sentinel*& y); template<bool OtherConst = !Const>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const iterator_t<*maybe-const*<OtherConst, V>>& x, const *sentinel*& y); };}
|
||
|
||
[ð](#lib:take_while_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
|
||
`
|
||
|
||
[1](#range.take.while.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6306)
|
||
|
||
*Effects*: Initializes *end_* with end and *pred_* with pred[.](#range.take.while.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:take_while_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> s)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.take.while.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6318)
|
||
|
||
*Effects*: Initializes *end_* with std::move(s.*end_*) and*pred_* with s.*pred_*[.](#range.take.while.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,take_while_view::sentinel)
|
||
|
||
`friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y);
|
||
|
||
template<bool OtherConst = !Const>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator_t<maybe-const<OtherConst, V>>& x,
|
||
const sentinel& y);
|
||
`
|
||
|
||
[3](#range.take.while.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6335)
|
||
|
||
*Effects*: Equivalent to:return y.*end_* == x || !invoke(*y.*pred_*, *x);
|
||
|
||
### [25.7.12](#range.drop) Drop view [[range.drop]](range.drop)
|
||
|
||
#### [25.7.12.1](#range.drop.overview) Overview [[range.drop.overview]](range.drop.overview)
|
||
|
||
[1](#range.drop.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6345)
|
||
|
||
drop_view produces a view
|
||
excluding the first N elements from another view, or
|
||
an empty range if the adapted view contains fewer than N elements[.](#range.drop.overview-1.sentence-1)
|
||
|
||
[2](#range.drop.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6350)
|
||
|
||
The name views::drop denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.drop.overview-2.sentence-1)
|
||
|
||
Let E and F be expressions,
|
||
let T be remove_cvref_t<decltype((E))>, and
|
||
let D be range_difference_t<decltype((E))>[.](#range.drop.overview-2.sentence-2)
|
||
|
||
If decltype((F)) does not model[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<D>,views::drop(E, F) is ill-formed[.](#range.drop.overview-2.sentence-3)
|
||
|
||
Otherwise, the expression views::drop(E, F) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.drop.overview-2.1)
|
||
|
||
If T is a specialization ofempty_view ([[range.empty.view]](range.empty.view "25.6.2.2 Class template empty_view")),
|
||
then ((void)F, *decay-copy*(E)),
|
||
except that the evaluations of E and F are indeterminately sequenced[.](#range.drop.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.drop.overview-2.2)
|
||
|
||
Otherwise, if T models[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") and [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]") and is
|
||
* [(2.2.1)](#range.drop.overview-2.2.1)
|
||
|
||
a specialization of span ([[views.span]](views.span "23.7.2.2 Class template span")),
|
||
|
||
* [(2.2.2)](#range.drop.overview-2.2.2)
|
||
|
||
a specialization of basic_string_view ([[string.view]](string.view "27.3 String view classes")),
|
||
|
||
* [(2.2.3)](#range.drop.overview-2.2.3)
|
||
|
||
a specialization of iota_view ([[range.iota.view]](range.iota.view "25.6.4.2 Class template iota_view")), or
|
||
|
||
* [(2.2.4)](#range.drop.overview-2.2.4)
|
||
|
||
a specialization of subrange ([[range.subrange]](range.subrange "25.5.4 Sub-ranges"))
|
||
where T::*StoreSize* is false,
|
||
|
||
then U(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E)),
|
||
except that E is evaluated only once,
|
||
where U is span<typename T::element_type> if T is a specialization of span and T otherwise[.](#range.drop.overview-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.drop.overview-2.3)
|
||
|
||
Otherwise,
|
||
if T is
|
||
a specialization of subrange that models [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") and [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"),
|
||
thenT(ranges::begin(E) + std::min<D>(ranges::distance(E), F), ranges::end(E),*to-unsigned-like*(ranges::distance(E) - std::min<D>(ranges::distance(E), F))),
|
||
except that E and F are each evaluated only once[.](#range.drop.overview-2.3.sentence-1)
|
||
|
||
- [(2.4)](#range.drop.overview-2.4)
|
||
|
||
Otherwise, if T is
|
||
a specialization of repeat_view ([[range.repeat.view]](range.repeat.view "25.6.5.2 Class template repeat_view")):
|
||
* [(2.4.1)](#range.drop.overview-2.4.1)
|
||
|
||
if T models [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]"),
|
||
thenviews::repeat(*E.*value_*, ranges::distance(E) - std::min<D>(ranges::distance(E), F)) except that E is evaluated only once;
|
||
|
||
* [(2.4.2)](#range.drop.overview-2.4.2)
|
||
|
||
otherwise, ((void)F, *decay-copy*(E)),
|
||
except that the evaluations of E and F are indeterminately sequenced[.](#range.drop.overview-2.4.sentence-1)
|
||
|
||
- [(2.5)](#range.drop.overview-2.5)
|
||
|
||
Otherwise, drop_view(E, F)[.](#range.drop.overview-2.5.sentence-1)
|
||
|
||
[3](#range.drop.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6417)
|
||
|
||
[*Example [1](#range.drop.overview-example-1)*: auto ints = views::iota(0) | views::take(10);for (auto i : ints | views::drop(5)) { cout << i << ' '; // prints 5 6 7 8 9} â *end example*]
|
||
|
||
#### [25.7.12.2](#range.drop.view) Class template drop_view [[range.drop.view]](range.drop.view)
|
||
|
||
[ð](#lib:drop_view)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>class drop_view : public view_interface<drop_view<V>> {public: drop_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit drop_view(V base, range_difference_t<V> count); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { 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]")<V> &&[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>)); constexpr auto begin() constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto end() requires (<V>){ return ranges::end(*base_*); }constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>{ return ranges::end(*base_*); }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> {const auto s = ranges::size(*base_*); const auto c = static_cast<decltype(s)>(*count_*); return s < c ? 0 : s - c; }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> {const auto s = ranges::size(*base_*); const auto c = static_cast<decltype(s)>(*count_*); return s < c ? 0 : s - c; }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V> {const auto s = static_cast<range_difference_t<V>>(ranges::reserve_hint(*base_*)); return *to-unsigned-like*(s < *count_* ? 0 : s - *count_*); }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]")<const V> {const auto s = static_cast<range_difference_t<const V>>(ranges::reserve_hint(*base_*)); return *to-unsigned-like*(s < *count_* ? 0 : s - *count_*); }private: V *base_* = V(); // *exposition only* range_difference_t<V> *count_* = 0; // *exposition only*}; template<class R> drop_view(R&&, range_difference_t<R>) -> drop_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:drop_view,constructor)
|
||
|
||
`constexpr explicit drop_view(V base, range_difference_t<V> count);
|
||
`
|
||
|
||
[1](#range.drop.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6494)
|
||
|
||
*Preconditions*: count >= 0 is true[.](#range.drop.view-1.sentence-1)
|
||
|
||
[2](#range.drop.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6498)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*count_* with count[.](#range.drop.view-2.sentence-1)
|
||
|
||
[ð](#lib:begin,drop_view)
|
||
|
||
`constexpr auto begin()
|
||
requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> &&
|
||
[random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>));
|
||
constexpr auto begin() const
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[3](#range.drop.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6514)
|
||
|
||
*Returns*: ranges::next(ranges::begin(*base_*), *count_*, ranges::end(*base_*))[.](#range.drop.view-3.sentence-1)
|
||
|
||
[4](#range.drop.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6518)
|
||
|
||
*Remarks*: In order to provide the amortized constant-time complexity required
|
||
by the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept
|
||
when drop_view models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
the first overload caches the result within the drop_view for use on subsequent calls[.](#range.drop.view-4.sentence-1)
|
||
|
||
[*Note [1](#range.drop.view-note-1)*:
|
||
|
||
Without this,
|
||
applying a reverse_view over a drop_view would have quadratic iteration complexity[.](#range.drop.view-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
### [25.7.13](#range.drop.while) Drop while view [[range.drop.while]](range.drop.while)
|
||
|
||
#### [25.7.13.1](#range.drop.while.overview) Overview [[range.drop.while.overview]](range.drop.while.overview)
|
||
|
||
[1](#range.drop.while.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6536)
|
||
|
||
Given a unary predicate pred and a view r,drop_while_view produces a view
|
||
of the range [ranges::find_if_not(r, pred), ranges::end(r))[.](#range.drop.while.overview-1.sentence-1)
|
||
|
||
[2](#range.drop.while.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6541)
|
||
|
||
The name views::drop_while denotes a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.drop.while.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F,
|
||
the expression views::drop_while(E, F) is expression-equivalent to drop_while_view(E, F)[.](#range.drop.while.overview-2.sentence-2)
|
||
|
||
[3](#range.drop.while.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6549)
|
||
|
||
[*Example [1](#range.drop.while.overview-example-1)*: constexpr auto source = " \t \t \t hello there"sv;auto is_invisible = [](const auto x) { return x == ' ' || x == '\t'; };auto skip_ws = views::drop_while(source, is_invisible);for (auto c : skip_ws) { cout << c; // prints hello there with no leading space} â *end example*]
|
||
|
||
#### [25.7.13.2](#range.drop.while.view) Class template drop_while_view [[range.drop.while.view]](range.drop.while.view)
|
||
|
||
[ð](#lib:drop_while_view)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V, class Pred>requires [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<V> && is_object_v<Pred> &&[indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<const Pred, iterator_t<V>>class drop_while_view : public view_interface<drop_while_view<V, Pred>> {public: drop_while_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pred> = default; constexpr explicit drop_while_view(V base, Pred pred); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr const Pred& pred() const; constexpr auto begin(); constexpr auto end() { return ranges::end(*base_*); }private: V *base_* = V(); // *exposition only**movable-box*<Pred> *pred_*; // *exposition only*}; template<class R, class Pred> drop_while_view(R&&, Pred) -> drop_while_view<views::all_t<R>, Pred>;}
|
||
|
||
[ð](#lib:drop_while_view,constructor)
|
||
|
||
`constexpr explicit drop_while_view(V base, Pred pred);
|
||
`
|
||
|
||
[1](#range.drop.while.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6601)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*pred_* with std::move(pred)[.](#range.drop.while.view-1.sentence-1)
|
||
|
||
[ð](#lib:pred,drop_while_view)
|
||
|
||
`constexpr const Pred& pred() const;
|
||
`
|
||
|
||
[2](#range.drop.while.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6613)
|
||
|
||
*Effects*: Equivalent to: return **pred_*;
|
||
|
||
[ð](#lib:begin,drop_while_view)
|
||
|
||
`constexpr auto begin();
|
||
`
|
||
|
||
[3](#range.drop.while.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6624)
|
||
|
||
*Preconditions*: *pred_*.has_value() is true[.](#range.drop.while.view-3.sentence-1)
|
||
|
||
[4](#range.drop.while.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6628)
|
||
|
||
*Returns*: ranges::find_if_not(*base_*, cref(**pred_*))[.](#range.drop.while.view-4.sentence-1)
|
||
|
||
[5](#range.drop.while.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6632)
|
||
|
||
*Remarks*: In order to provide the amortized constant-time complexity
|
||
required by the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept
|
||
when drop_while_view models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
the first call caches the result within the drop_while_view for use on subsequent calls[.](#range.drop.while.view-5.sentence-1)
|
||
|
||
[*Note [1](#range.drop.while.view-note-1)*:
|
||
|
||
Without this,
|
||
applying a reverse_view over a drop_while_view would have quadratic iteration complexity[.](#range.drop.while.view-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
### [25.7.14](#range.join) Join view [[range.join]](range.join)
|
||
|
||
#### [25.7.14.1](#range.join.overview) Overview [[range.join.overview]](range.join.overview)
|
||
|
||
[1](#range.join.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6650)
|
||
|
||
join_view flattens a view of ranges into a view[.](#range.join.overview-1.sentence-1)
|
||
|
||
[2](#range.join.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6653)
|
||
|
||
The name views::join denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.join.overview-2.sentence-1)
|
||
|
||
Given a subexpression E, the expressionviews::join(E) is expression-equivalent tojoin_view<views::all_t<decltype((E))>>{E}[.](#range.join.overview-2.sentence-2)
|
||
|
||
[3](#range.join.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6661)
|
||
|
||
[*Example [1](#range.join.overview-example-1)*: vector<string> ss{"hello", " ", "world", "!"};for (char ch : ss | views::join) cout << ch; // prints hello world! â *end example*]
|
||
|
||
#### [25.7.14.2](#range.join.view) Class template join_view [[range.join.view]](range.join.view)
|
||
|
||
[ð](#lib:join_view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>class join_view : public view_interface<join_view<V>> {private:using *InnerRng* = range_reference_t<V>; // *exposition only*// [[range.join.iterator]](#range.join.iterator "25.7.14.3 Class template join_view::iterator"), class template join_view::*iterator*template<bool Const>struct *iterator*; // *exposition only*// [[range.join.sentinel]](#range.join.sentinel "25.7.14.4 Class template join_view::sentinel"), class template join_view::*sentinel*template<bool Const>struct *sentinel*; // *exposition only* V *base_* = V(); // *exposition only**non-propagating-cache*<iterator_t<V>> *outer_*; // *exposition only*, present only// when <V>*non-propagating-cache*<remove_cv_t<*InnerRng*>> *inner_*; // *exposition only*, present only// if is_reference_v<*InnerRng*> is falsepublic: join_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit join_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>) {constexpr bool use_const = [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && is_reference_v<*InnerRng*>; return *iterator*<use_const>{*this, ranges::begin(*base_*)}; } else {*outer_* = ranges::begin(*base_*); return *iterator*<false>{*this}; }}constexpr auto begin() constrequires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> && is_reference_v<range_reference_t<const V>> &&[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>>{ return *iterator*<true>{*this, ranges::begin(*base_*)}; }constexpr auto end() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && is_reference_v<*InnerRng*> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*InnerRng*> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*InnerRng*>)return *iterator*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V>>{*this, ranges::end(*base_*)}; elsereturn *sentinel*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V>>{*this}; }constexpr auto end() constrequires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> && is_reference_v<range_reference_t<const V>> &&[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>> {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>>)return *iterator*<true>{*this, ranges::end(*base_*)}; elsereturn *sentinel*<true>{*this}; }}; template<class R>explicit join_view(R&&) -> join_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:join_view,constructor)
|
||
|
||
`constexpr explicit join_view(V base);
|
||
`
|
||
|
||
[1](#range.join.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6756)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.join.view-1.sentence-1)
|
||
|
||
#### [25.7.14.3](#range.join.iterator) Class template join_view::*iterator* [[range.join.iterator]](range.join.iterator)
|
||
|
||
[ð](#lib:join_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>template<bool Const>struct join_view<V>::*iterator* {private:using *Parent* = *maybe-const*<Const, join_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only*using *OuterIter* = iterator_t<*Base*>; // *exposition only*using *InnerIter* = iterator_t<range_reference_t<*Base*>>; // *exposition only*static constexpr bool *ref-is-glvalue* = // *exposition only* is_reference_v<range_reference_t<*Base*>>; *OuterIter* *outer_* = *OuterIter*(); // *exposition only*, present only// if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") optional<*InnerIter*> *inner_*; // *exposition only**Parent** *parent_* = nullptr; // *exposition only*constexpr void *satisfy*(); // *exposition only*constexpr *OuterIter*& *outer*(); // *exposition only*constexpr const *OuterIter*& *outer*() const; // *exposition only*constexpr *iterator*(*Parent*& parent, *OuterIter* outer)requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; // *exposition only*constexpr explicit *iterator*(*Parent*& parent)requires (<*Base*>); // *exposition only*public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = range_value_t<range_reference_t<*Base*>>; using difference_type = *see below*; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, *OuterIter*> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<*InnerRng*>, *InnerIter*>; constexpr decltype(auto) operator*() const { return ***inner_*; }constexpr *InnerIter* operator->() constrequires [*has-arrow*](range.utility.helpers#concept:has-arrow "25.5.2 Helper concepts [range.utility.helpers]")<*InnerIter*> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<*InnerIter*>; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int)requires *ref-is-glvalue* && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<*Base*>>; constexpr *iterator*& operator--()requires *ref-is-glvalue* && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<*Base*>> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<*Base*>>; constexpr *iterator* operator--(int)requires *ref-is-glvalue* && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<*Base*>> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<*Base*>>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires *ref-is-glvalue* && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<range_reference_t<*Base*>>>; friend constexpr decltype(auto) iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(*i.*inner_*))) {return ranges::iter_move(*i.*inner_*); }friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)noexcept(noexcept(ranges::iter_swap(*x.*inner_*, *y.*inner_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<*InnerIter*>; };}
|
||
|
||
[1](#range.join.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6843)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.join.iterator-1.1)
|
||
|
||
If *ref-is-glvalue* is true, *Base* models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"), and range_reference_t<*Base*> models
|
||
both [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]") and [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes bidirectional_iterator_tag[.](#range.join.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.join.iterator-1.2)
|
||
|
||
Otherwise, if *ref-is-glvalue* is true and *Base* and range_reference_t<*Base*> each model [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"), then iterator_concept denotes forward_iterator_tag[.](#range.join.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.join.iterator-1.3)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.join.iterator-1.3.sentence-1)
|
||
|
||
[2](#range.join.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6858)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if *ref-is-glvalue* is true,*Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"), andrange_reference_t<*Base*> models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.join.iterator-2.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
|
||
- [(2.1)](#range.join.iterator-2.1)
|
||
|
||
Let *OUTERC* denote iterator_traits<iterator_t<*Base*>>::iterator_category, and
|
||
let *INNERC* denote iterator_traits<iterator_t<range_reference_t<*Base*>>>::iterator_category[.](#range.join.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.join.iterator-2.2)
|
||
|
||
If *OUTERC* and *INNERC* each model [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<bidirectional_iterator_tag> and range_reference_t<*Base*> models [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"), iterator_category denotes bidirectional_iterator_tag[.](#range.join.iterator-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.join.iterator-2.3)
|
||
|
||
Otherwise, if *OUTERC* and *INNERC* each model [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<forward_iterator_tag>, iterator_category denotes forward_iterator_tag[.](#range.join.iterator-2.3.sentence-1)
|
||
|
||
- [(2.4)](#range.join.iterator-2.4)
|
||
|
||
Otherwise, iterator_category denotes input_iterator_tag[.](#range.join.iterator-2.4.sentence-1)
|
||
|
||
[3](#range.join.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6883)
|
||
|
||
*iterator*::difference_type denotes the type:common_type_t< range_difference_t<*Base*>,
|
||
range_difference_t<range_reference_t<*Base*>>>
|
||
|
||
[4](#range.join.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6891)
|
||
|
||
join_view iterators use the *satisfy* function to skip over
|
||
empty inner ranges[.](#range.join.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:outer,join_view::iterator)
|
||
|
||
`constexpr OuterIter& outer();
|
||
constexpr const OuterIter& outer() const;
|
||
`
|
||
|
||
[5](#range.join.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6902)
|
||
|
||
*Returns*: *outer_* if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]");
|
||
otherwise, **parent_*->*outer_*[.](#range.join.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:satisfy,join_view::iterator)
|
||
|
||
`constexpr void satisfy();
|
||
`
|
||
|
||
[6](#range.join.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6914)
|
||
|
||
*Effects*: Equivalent to:auto update_inner = [this](const iterator_t<*Base*>& x) -> auto&& {if constexpr (*ref-is-glvalue*) // *x is a referencereturn *x; elsereturn *parent_*->*inner_*.*emplace-deref*(x);};
|
||
|
||
for (; *outer*() != ranges::end(*parent_*->*base_*); ++*outer*()) {auto&& inner = update_inner(*outer*()); *inner_* = ranges::begin(inner); if (**inner_* != ranges::end(inner))return;}if constexpr (*ref-is-glvalue*)*inner_*.reset();
|
||
|
||
[ð](#lib:join_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent& parent, OuterIter outer)
|
||
requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[7](#range.join.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6943)
|
||
|
||
*Effects*: Initializes *outer_* with std::move(outer) and*parent_* with addressof(parent); then calls *satisfy*()[.](#range.join.iterator-7.sentence-1)
|
||
|
||
[ð](#lib:join_view::iterator,constructor_)
|
||
|
||
`constexpr explicit iterator(Parent& parent)
|
||
requires (<Base>);
|
||
`
|
||
|
||
[8](#range.join.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6956)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent);
|
||
then calls *satisfy*()[.](#range.join.iterator-8.sentence-1)
|
||
|
||
[ð](#lib:join_view::iterator,constructor__)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const &&
|
||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, OuterIter> &&
|
||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<InnerRng>, InnerIter>;
|
||
`
|
||
|
||
[9](#range.join.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6971)
|
||
|
||
*Effects*: Initializes *outer_* with std::move(i.*outer_*),*inner_* with std::move(i.*inner_*), and*parent_* with i.*parent_*[.](#range.join.iterator-9.sentence-1)
|
||
|
||
[10](#range.join.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6977)
|
||
|
||
[*Note [1](#range.join.iterator-note-1)*:
|
||
|
||
Const can only be true when *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.join.iterator-10.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator-%3e,join_view::iterator)
|
||
|
||
`constexpr InnerIter operator->() const
|
||
requires [has-arrow](range.utility.helpers#concept:has-arrow "25.5.2 Helper concepts [range.utility.helpers]")<InnerIter> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<InnerIter>;
|
||
`
|
||
|
||
[11](#range.join.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6991)
|
||
|
||
*Effects*: Equivalent to: return **inner_*;
|
||
|
||
[ð](#lib:operator++,join_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[12](#range.join.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7002)
|
||
|
||
Let *inner-range* be:
|
||
|
||
- [(12.1)](#range.join.iterator-12.1)
|
||
|
||
If *ref-is-glvalue* is true, **outer*()[.](#range.join.iterator-12.1.sentence-1)
|
||
|
||
- [(12.2)](#range.join.iterator-12.2)
|
||
|
||
Otherwise, **parent_*->*inner_*[.](#range.join.iterator-12.2.sentence-1)
|
||
|
||
[13](#range.join.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7009)
|
||
|
||
*Effects*: Equivalent to:if (++**inner_* == ranges::end(*as-lvalue*(*inner-range*))) {++*outer*(); *satisfy*();}return *this;
|
||
|
||
[ð](#lib:operator++,join_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[14](#range.join.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7027)
|
||
|
||
*Effects*: Equivalent to: ++*this[.](#range.join.iterator-14.sentence-1)
|
||
|
||
[ð](#lib:operator++,join_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int)
|
||
requires ref-is-glvalue && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<Base>>;
|
||
`
|
||
|
||
[15](#range.join.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7040)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,join_view::iterator)
|
||
|
||
`constexpr iterator& operator--()
|
||
requires ref-is-glvalue && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<Base>> &&
|
||
[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<Base>>;
|
||
`
|
||
|
||
[16](#range.join.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7059)
|
||
|
||
*Effects*: Equivalent to:if (*outer_* == ranges::end(*parent_*->*base_*))*inner_* = ranges::end(*as-lvalue*(*--*outer_*));while (**inner_* == ranges::begin(*as-lvalue*(**outer_*)))**inner_* = ranges::end(*as-lvalue*(*--*outer_*));--**inner_*;return *this;
|
||
|
||
[ð](#lib:operator--,join_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int)
|
||
requires ref-is-glvalue && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<Base>> &&
|
||
[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<Base>>;
|
||
`
|
||
|
||
[17](#range.join.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7081)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator==,join_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires ref-is-glvalue && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<range_reference_t<Base>>>;
|
||
`
|
||
|
||
[18](#range.join.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7099)
|
||
|
||
*Effects*: Equivalent to:return x.*outer_* == y.*outer_* && x.*inner_* == y.*inner_*;
|
||
|
||
[ð](#lib:iter_swap,join_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
||
noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<InnerIter>;
|
||
`
|
||
|
||
[19](#range.join.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7113)
|
||
|
||
*Effects*: Equivalent to: ranges::iter_swap(*x.*inner_*, *y.*inner_*);
|
||
|
||
#### [25.7.14.4](#range.join.sentinel) Class template join_view::*sentinel* [[range.join.sentinel]](range.join.sentinel)
|
||
|
||
[ð](#lib:join_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>template<bool Const>struct join_view<V>::*sentinel* {private:using *Parent* = *maybe-const*<Const, join_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(*Parent*& parent); constexpr *sentinel*(*sentinel*<!Const> s)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); };}
|
||
|
||
[ð](#lib:join_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(Parent& parent);
|
||
`
|
||
|
||
[1](#range.join.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7152)
|
||
|
||
*Effects*: Initializes *end_* with ranges::end(parent.*base_*)[.](#range.join.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:join_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> s)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.join.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7164)
|
||
|
||
*Effects*: Initializes *end_* with std::move(s.*end_*)[.](#range.join.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,join_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.join.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7177)
|
||
|
||
*Effects*: Equivalent to: return x.*outer*() == y.*end_*;
|
||
|
||
### [25.7.15](#range.join.with) Join with view [[range.join.with]](range.join.with)
|
||
|
||
#### [25.7.15.1](#range.join.with.overview) Overview [[range.join.with.overview]](range.join.with.overview)
|
||
|
||
[1](#range.join.with.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7186)
|
||
|
||
join_with_view takes a view and a delimiter, and
|
||
flattens the view,
|
||
inserting every element of the delimiter
|
||
in between elements of the view[.](#range.join.with.overview-1.sentence-1)
|
||
|
||
The delimiter can be a single element or a view of elements[.](#range.join.with.overview-1.sentence-2)
|
||
|
||
[2](#range.join.with.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7193)
|
||
|
||
The name views::join_with denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.join.with.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F,
|
||
the expression views::join_with(E, F) is expression-equivalent tojoin_with_view(E, F)[.](#range.join.with.overview-2.sentence-2)
|
||
|
||
[3](#range.join.with.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7201)
|
||
|
||
[*Example [1](#range.join.with.overview-example-1)*: vector<string> vs = {"the", "quick", "brown", "fox"};for (char c : vs | views::join_with('-')) { cout << c;}// The above prints the-quick-brown-fox â *end example*]
|
||
|
||
#### [25.7.15.2](#range.join.with.view) Class template join_with_view [[range.join.with.view]](range.join.with.view)
|
||
|
||
[ð](#lib:join_with_view)
|
||
|
||
namespace std::ranges {template<class R>concept [*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]") = [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<R> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<R>; // *exposition only*template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>&& [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern>&& [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<range_reference_t<V>, Pattern>class join_with_view : public view_interface<join_with_view<V, Pattern>> {using *InnerRng* = range_reference_t<V>; // *exposition only* V *base_* = V(); // *exposition only**non-propagating-cache*<iterator_t<V>> *outer_it_*; // *exposition only*, present only// when <V>*non-propagating-cache*<remove_cv_t<*InnerRng*>> *inner_*; // *exposition only*, present only// if is_reference_v<*InnerRng*> is false Pattern *pattern_* = Pattern(); // *exposition only*// [[range.join.with.iterator]](#range.join.with.iterator "25.7.15.3 Class template join_with_view::iterator"), class template join_with_view::*iterator*template<bool Const> struct *iterator*; // *exposition only*// [[range.join.with.sentinel]](#range.join.with.sentinel "25.7.15.4 Class template join_with_view::sentinel"), class template join_with_view::*sentinel*template<bool Const> struct *sentinel*; // *exposition only*public: join_with_view()requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pattern> = default; constexpr explicit join_with_view(V base, Pattern pattern); template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<V, views::all_t<R>> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<Pattern, single_view<range_value_t<*InnerRng*>>>constexpr explicit join_with_view(R&& r, range_value_t<*InnerRng*> e); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>) {constexpr bool use_const =[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && is_reference_v<*InnerRng*> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>; return *iterator*<use_const>{*this, ranges::begin(*base_*)}; }else {*outer_it_* = ranges::begin(*base_*); return *iterator*<false>{*this}; }}constexpr auto begin() constrequires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> &&[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const Pattern> && is_reference_v<range_reference_t<const V>> &&[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>> &&[*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<range_reference_t<const V>, const Pattern> {return *iterator*<true>{*this, ranges::begin(*base_*)}; }constexpr auto end() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && is_reference_v<*InnerRng*> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*InnerRng*> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*InnerRng*>)return *iterator*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>>{*this, ranges::end(*base_*)}; elsereturn *sentinel*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>>{*this}; }constexpr auto end() constrequires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const Pattern> && is_reference_v<range_reference_t<const V>> &&[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<const V>> &&[*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<range_reference_t<const V>, const Pattern> {using InnerConstRng = range_reference_t<const V>; if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<InnerConstRng> &&[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<InnerConstRng>)return *iterator*<true>{*this, ranges::end(*base_*)}; elsereturn *sentinel*<true>{*this}; }}; template<class R, class P> join_with_view(R&&, P&&) -> join_with_view<views::all_t<R>, views::all_t<P>>; template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R> join_with_view(R&&, range_value_t<range_reference_t<R>>)-> join_with_view<views::all_t<R>, single_view<range_value_t<range_reference_t<R>>>>;}
|
||
|
||
[ð](#lib:join_with_view,constructor)
|
||
|
||
`constexpr explicit join_with_view(V base, Pattern pattern);
|
||
`
|
||
|
||
[1](#range.join.with.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7311)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*pattern_* with std::move(pattern)[.](#range.join.with.view-1.sentence-1)
|
||
|
||
[ð](#lib:join_with_view,constructor_)
|
||
|
||
`template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
|
||
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<V, views::all_t<R>> &&
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<Pattern, single_view<range_value_t<InnerRng>>>
|
||
constexpr explicit join_with_view(R&& r, range_value_t<InnerRng> e);
|
||
`
|
||
|
||
[2](#range.join.with.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7326)
|
||
|
||
*Effects*: Initializes *base_* with views::all(std::forward<R>(r)) and*pattern_* with views::single(std::move(e))[.](#range.join.with.view-2.sentence-1)
|
||
|
||
#### [25.7.15.3](#range.join.with.iterator) Class template join_with_view::*iterator* [[range.join.with.iterator]](range.join.with.iterator)
|
||
|
||
[ð](#lib:join_with_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>&& [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> && [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<range_reference_t<V>, Pattern>template<bool Const>class join_with_view<V, Pattern>::*iterator* {using *Parent* = *maybe-const*<Const, join_with_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only*using *InnerBase* = range_reference_t<*Base*>; // *exposition only*using *PatternBase* = *maybe-const*<Const, Pattern>; // *exposition only*using *OuterIter* = iterator_t<*Base*>; // *exposition only*using *InnerIter* = iterator_t<*InnerBase*>; // *exposition only*using *PatternIter* = iterator_t<*PatternBase*>; // *exposition only*static constexpr bool *ref-is-glvalue* = is_reference_v<*InnerBase*>; // *exposition only**Parent** *parent_* = nullptr; // *exposition only**OuterIter* *outer_it_* = *OuterIter*(); // *exposition only*, present only// if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") variant<*PatternIter*, *InnerIter*> *inner_it_*; // *exposition only*constexpr *iterator*(*Parent*& parent, *OuterIter* outer)requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; // *exposition only*constexpr explicit *iterator*(*Parent*& parent)requires (<*Base*>); // *exposition only*constexpr *OuterIter*& *outer*(); // *exposition only*constexpr const *OuterIter*& *outer*() const; // *exposition only*constexpr auto& *update-inner*(); // *exposition only*constexpr auto& *get-inner*(); // *exposition only*constexpr void *satisfy*(); // *exposition only*public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = *see below*; using difference_type = *see below*; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, *OuterIter*> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<*InnerRng*>, *InnerIter*> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Pattern>, *PatternIter*>; constexpr decltype(auto) operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int)requires *ref-is-glvalue* && [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<*OuterIter*> &&[forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<*InnerIter*>; constexpr *iterator*& operator--()requires *ref-is-glvalue* && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<*InnerBase*> && [*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<*PatternBase*>; constexpr *iterator* operator--(int)requires *ref-is-glvalue* && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<*InnerBase*> && [*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<*PatternBase*>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires *ref-is-glvalue* && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*> &&[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<*InnerIter*>; friend constexpr decltype(auto) iter_move(const *iterator*& x) {using rvalue_reference = common_reference_t< iter_rvalue_reference_t<*InnerIter*>,
|
||
iter_rvalue_reference_t<*PatternIter*>>; return visit<rvalue_reference>(ranges::iter_move, x.*inner_it_*); }friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<*InnerIter*, *PatternIter*> { visit(ranges::iter_swap, x.*inner_it_*, y.*inner_it_*); }};}
|
||
|
||
[1](#range.join.with.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7414)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.join.with.iterator-1.1)
|
||
|
||
If *ref-is-glvalue* is true,*Base* models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"), and*InnerBase* and *PatternBase* each model [*bidirectional-common*](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]"),
|
||
then iterator_concept denotes bidirectional_iterator_tag[.](#range.join.with.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.join.with.iterator-1.2)
|
||
|
||
Otherwise, if *ref-is-glvalue* is true and*Base* and *InnerBase* each model [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.join.with.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.join.with.iterator-1.3)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.join.with.iterator-1.3.sentence-1)
|
||
|
||
[2](#range.join.with.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7431)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if *ref-is-glvalue* is true, and*Base* and *InnerBase* each model [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.join.with.iterator-2.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
|
||
- [(2.1)](#range.join.with.iterator-2.1)
|
||
|
||
Let *OUTERC* denoteiterator_traits<*OuterIter*>::iterator_category,
|
||
let *INNERC* denoteiterator_traits<*InnerIter*>::iterator_category, and
|
||
let *PATTERNC* denoteiterator_traits<*PatternIter*>::iterator_category[.](#range.join.with.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.join.with.iterator-2.2)
|
||
|
||
Ifis_reference_v<common_reference_t<iter_reference_t<*InnerIter*>,
|
||
iter_reference_t<*PatternIter*>>> is false,iterator_category denotes input_iterator_tag[.](#range.join.with.iterator-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.join.with.iterator-2.3)
|
||
|
||
Otherwise,
|
||
if *OUTERC*, *INNERC*, and *PATTERNC* each model [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<bidirectional_iterator_tag> and *InnerBase* and *PatternBase* each model [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"),iterator_category denotes bidirectional_iterator_tag[.](#range.join.with.iterator-2.3.sentence-1)
|
||
|
||
- [(2.4)](#range.join.with.iterator-2.4)
|
||
|
||
Otherwise,
|
||
if *OUTERC*, *INNERC*, and *PATTERNC* each model [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<forward_iterator_tag>,iterator_category denotes forward_iterator_tag[.](#range.join.with.iterator-2.4.sentence-1)
|
||
|
||
- [(2.5)](#range.join.with.iterator-2.5)
|
||
|
||
Otherwise, iterator_category denotes input_iterator_tag[.](#range.join.with.iterator-2.5.sentence-1)
|
||
|
||
[3](#range.join.with.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7469)
|
||
|
||
*iterator*::value_type denotes the type:common_type_t<iter_value_t<*InnerIter*>, iter_value_t<*PatternIter*>>
|
||
|
||
[4](#range.join.with.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7475)
|
||
|
||
*iterator*::difference_type denotes the type:common_type_t< iter_difference_t<*OuterIter*>,
|
||
iter_difference_t<*InnerIter*>,
|
||
iter_difference_t<*PatternIter*>>
|
||
|
||
[ð](#lib:outer,join_with_view::iterator)
|
||
|
||
`constexpr OuterIter& outer();
|
||
constexpr const OuterIter& outer() const;
|
||
`
|
||
|
||
[5](#range.join.with.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7491)
|
||
|
||
*Returns*: *outer_it_* if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]");
|
||
otherwise, **parent_*->*outer_it_*[.](#range.join.with.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:update-inner,join_with_view::iterator)
|
||
|
||
`constexpr auto& update-inner();
|
||
`
|
||
|
||
[6](#range.join.with.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7503)
|
||
|
||
*Effects*: Equivalent to:if constexpr (*ref-is-glvalue*)return *as-lvalue*(**outer*());elsereturn *parent_*->*inner_*.*emplace-deref*(*outer*());
|
||
|
||
[ð](#lib:get-inner,join_with_view::iterator)
|
||
|
||
`constexpr auto& get-inner();
|
||
`
|
||
|
||
[7](#range.join.with.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7520)
|
||
|
||
*Effects*: Equivalent to:if constexpr (*ref-is-glvalue*)return *as-lvalue*(**outer*());elsereturn **parent_*->*inner_*;
|
||
|
||
[ð](#lib:satisfy,join_with_view::iterator)
|
||
|
||
`constexpr void satisfy();
|
||
`
|
||
|
||
[8](#range.join.with.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7537)
|
||
|
||
*Effects*: Equivalent to:while (true) {if (*inner_it_*.index() == 0) {if (std::get<0>(*inner_it_*) != ranges::end(*parent_*->*pattern_*))break; *inner_it_*.template emplace<1>(ranges::begin(*update-inner*())); } else {if (std::get<1>(*inner_it_*) != ranges::end(*get-inner*()))break; if (++*outer*() == ranges::end(*parent_*->*base_*)) {if constexpr (*ref-is-glvalue*)*inner_it_*.template emplace<0>(); break; }*inner_it_*.template emplace<0>(ranges::begin(*parent_*->*pattern_*)); }}
|
||
|
||
[*Note [1](#range.join.with.iterator-note-1)*:
|
||
|
||
join_with_view iterators use the *satisfy* function
|
||
to skip over empty inner ranges[.](#range.join.with.iterator-8.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:join_with_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent& parent, OuterIter outer)
|
||
requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
constexpr explicit iterator(Parent& parent)
|
||
requires (<Base>);
|
||
`
|
||
|
||
[9](#range.join.with.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7574)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent)[.](#range.join.with.iterator-9.sentence-1)
|
||
|
||
For the first overload, also initializes*outer_it_* with std::move(outer)[.](#range.join.with.iterator-9.sentence-2)
|
||
|
||
Then, equivalent to:if (*outer*() != ranges::end(*parent_*->*base_*)) {*inner_it_*.template emplace<1>(ranges::begin(*update-inner*())); *satisfy*();}
|
||
|
||
[ð](#lib:join_with_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, OuterIter> &&
|
||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<InnerRng>, InnerIter> &&
|
||
[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Pattern>, PatternIter>;
|
||
`
|
||
|
||
[10](#range.join.with.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7597)
|
||
|
||
*Effects*: Initializes *outer_it_* withstd::move(i.*outer_it_*) and*parent_* with i.*parent_*[.](#range.join.with.iterator-10.sentence-1)
|
||
|
||
Then, equivalent to:if (i.*inner_it_*.index() == 0)*inner_it_*.template emplace<0>(std::get<0>(std::move(i.*inner_it_*)));else*inner_it_*.template emplace<1>(std::get<1>(std::move(i.*inner_it_*)));
|
||
|
||
[11](#range.join.with.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7610)
|
||
|
||
[*Note [2](#range.join.with.iterator-note-2)*:
|
||
|
||
Const can only be true when *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.join.with.iterator-11.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator--,join_with_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator*() const;
|
||
`
|
||
|
||
[12](#range.join.with.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7623)
|
||
|
||
*Effects*: Equivalent to:using reference = common_reference_t<iter_reference_t<*InnerIter*>, iter_reference_t<*PatternIter*>>;return visit([](auto& it) -> reference { return *it; }, *inner_it_*);
|
||
|
||
[ð](#lib:operator++,join_with_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[13](#range.join.with.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7639)
|
||
|
||
*Effects*: Equivalent to:visit([](auto& it){ ++it; }, *inner_it_*);*satisfy*();return *this;
|
||
|
||
[ð](#lib:operator++,join_with_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[14](#range.join.with.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7655)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.join.with.iterator-14.sentence-1)
|
||
|
||
[ð](#lib:operator++,join_with_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int)
|
||
requires ref-is-glvalue && [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<OuterIter> && [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<InnerIter>;
|
||
`
|
||
|
||
[15](#range.join.with.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7667)
|
||
|
||
*Effects*: Equivalent to:*iterator* tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,join_with_view::iterator_)
|
||
|
||
`constexpr iterator& operator--()
|
||
requires ref-is-glvalue && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[bidirectional-common](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<InnerBase> && [bidirectional-common](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<PatternBase>;
|
||
`
|
||
|
||
[16](#range.join.with.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7685)
|
||
|
||
*Effects*: Equivalent to:if (*outer_it_* == ranges::end(*parent_*->*base_*)) {auto&& inner = *--*outer_it_*; *inner_it_*.template emplace<1>(ranges::end(inner));}while (true) {if (*inner_it_*.index() == 0) {auto& it = std::get<0>(*inner_it_*); if (it == ranges::begin(*parent_*->*pattern_*)) {auto&& inner = *--*outer_it_*; *inner_it_*.template emplace<1>(ranges::end(inner)); } else {break; }} else {auto& it = std::get<1>(*inner_it_*); auto&& inner = **outer_it_*; if (it == ranges::begin(inner)) {*inner_it_*.template emplace<0>(ranges::end(*parent_*->*pattern_*)); } else {break; }}} visit([](auto& it){ --it; }, *inner_it_*);return *this;
|
||
|
||
[ð](#lib:operator--,join_with_view::iterator__)
|
||
|
||
`constexpr iterator operator--(int)
|
||
requires ref-is-glvalue && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[bidirectional-common](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<InnerBase> && [bidirectional-common](#concept:bidirectional-common "25.7.15.2 Class template join_with_view [range.join.with.view]")<PatternBase>;
|
||
`
|
||
|
||
[17](#range.join.with.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7726)
|
||
|
||
*Effects*: Equivalent to:*iterator* tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator==,join_with_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires ref-is-glvalue && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base> &&
|
||
[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<InnerIter>;
|
||
`
|
||
|
||
[18](#range.join.with.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7744)
|
||
|
||
*Effects*: Equivalent to:return x.*outer_it_* == y.*outer_it_* && x.*inner_it_* == y.*inner_it_*;
|
||
|
||
#### [25.7.15.4](#range.join.with.sentinel) Class template join_with_view::*sentinel* [[range.join.with.sentinel]](range.join.with.sentinel)
|
||
|
||
[ð](#lib:join_with_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<range_reference_t<V>>&& [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> && [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<range_reference_t<V>, Pattern>template<bool Const>class join_with_view<V, Pattern>::*sentinel* {using *Parent* = *maybe-const*<Const, join_with_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*constexpr explicit *sentinel*(*Parent*& parent); // *exposition only*public:*sentinel*() = default; constexpr *sentinel*(*sentinel*<!Const> s)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); };}
|
||
|
||
[ð](#lib:join_with_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(Parent& parent);
|
||
`
|
||
|
||
[1](#range.join.with.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7786)
|
||
|
||
*Effects*: Initializes *end_* with ranges::end(parent.*base_*)[.](#range.join.with.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:join_with_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> s)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.join.with.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7798)
|
||
|
||
*Effects*: Initializes *end_* with std::move(s.*end_*)[.](#range.join.with.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,join_with_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.join.with.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7811)
|
||
|
||
*Effects*: Equivalent to: return x.*outer*() == y.*end_*;
|
||
|
||
### [25.7.16](#range.lazy.split) Lazy split view [[range.lazy.split]](range.lazy.split)
|
||
|
||
#### [25.7.16.1](#range.lazy.split.overview) Overview [[range.lazy.split.overview]](range.lazy.split.overview)
|
||
|
||
[1](#range.lazy.split.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7820)
|
||
|
||
lazy_split_view takes a view and a delimiter, and splits
|
||
the view into subranges on the delimiter[.](#range.lazy.split.overview-1.sentence-1)
|
||
|
||
The delimiter can be
|
||
a single element or a view of elements[.](#range.lazy.split.overview-1.sentence-2)
|
||
|
||
[2](#range.lazy.split.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7825)
|
||
|
||
The name views::lazy_split denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.lazy.split.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F,
|
||
the expression views::lazy_split(E, F) is expression-equivalent tolazy_split_view(E, F)[.](#range.lazy.split.overview-2.sentence-2)
|
||
|
||
[3](#range.lazy.split.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7833)
|
||
|
||
[*Example [1](#range.lazy.split.overview-example-1)*: string str{"the quick brown fox"};for (auto word : str | views::lazy_split(' ')) {for (char ch : word) cout << ch;
|
||
cout << '*';}// The above prints the*quick*brown*fox* â *end example*]
|
||
|
||
#### [25.7.16.2](#range.lazy.split.view) Class template lazy_split_view [[range.lazy.split.view]](range.lazy.split.view)
|
||
|
||
[ð](#lib:lazy_split_view)
|
||
|
||
namespace std::ranges {template<auto> struct *require-constant*; // *exposition only*template<class R>concept [*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]") = // *exposition only*[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R> &&requires { typename *require-constant*<remove_reference_t<R>::size()>; } &&(remove_reference_t<R>::size() <= 1); template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> || [*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]")<Pattern>)class lazy_split_view : public view_interface<lazy_split_view<V, Pattern>> {private: V *base_* = V(); // *exposition only* Pattern *pattern_* = Pattern(); // *exposition only**non-propagating-cache*<iterator_t<V>> *current_*; // *exposition only*, present only// if [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> is false// [[range.lazy.split.outer]](#range.lazy.split.outer "25.7.16.3 Class template lazy_split_view::outer-iterator"), class template lazy_split_view::*outer-iterator*template<bool> struct *outer-iterator*; // *exposition only*// [[range.lazy.split.inner]](#range.lazy.split.inner "25.7.16.5 Class template lazy_split_view::inner-iterator"), class template lazy_split_view::*inner-iterator*template<bool> struct *inner-iterator*; // *exposition only*public: lazy_split_view()requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pattern> = default; constexpr explicit lazy_split_view(V base, Pattern pattern); template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<V, views::all_t<R>> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<Pattern, single_view<range_value_t<R>>>constexpr explicit lazy_split_view(R&& r, range_value_t<R> e); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>) {return *outer-iterator*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>>{*this, ranges::begin(*base_*)}; } else {*current_* = ranges::begin(*base_*); return *outer-iterator*<false>{*this}; }}constexpr auto begin() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> {return *outer-iterator*<true>{*this, ranges::begin(*base_*)}; }constexpr auto end() requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> {return *outer-iterator*<[*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Pattern>>{*this, ranges::end(*base_*)}; }constexpr auto end() const {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>)return *outer-iterator*<true>{*this, ranges::end(*base_*)}; elsereturn default_sentinel; }}; template<class R, class P> lazy_split_view(R&&, P&&) -> lazy_split_view<views::all_t<R>, views::all_t<P>>; template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R> lazy_split_view(R&&, range_value_t<R>)-> lazy_split_view<views::all_t<R>, single_view<range_value_t<R>>>;}
|
||
|
||
[ð](#lib:lazy_split_view,constructor)
|
||
|
||
`constexpr explicit lazy_split_view(V base, Pattern pattern);
|
||
`
|
||
|
||
[1](#range.lazy.split.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7935)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base), and*pattern_* with std::move(pattern)[.](#range.lazy.split.view-1.sentence-1)
|
||
|
||
[ð](#lib:lazy_split_view,constructor_)
|
||
|
||
`template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
|
||
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<V, views::all_t<R>> &&
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<Pattern, single_view<range_value_t<R>>>
|
||
constexpr explicit lazy_split_view(R&& r, range_value_t<R> e);
|
||
`
|
||
|
||
[2](#range.lazy.split.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7950)
|
||
|
||
*Effects*: Initializes *base_* with views::all(std::forward<R>(r)), and*pattern_* with views::single(std::move(e))[.](#range.lazy.split.view-2.sentence-1)
|
||
|
||
#### [25.7.16.3](#range.lazy.split.outer) Class template lazy_split_view::*outer-iterator* [[range.lazy.split.outer]](range.lazy.split.outer)
|
||
|
||
[ð](#lib:lazy_split_view::outer-iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> || [*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]")<Pattern>)template<bool Const>struct lazy_split_view<V, Pattern>::*outer-iterator* {private:using *Parent* = *maybe-const*<Const, lazy_split_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only**Parent** *parent_* = nullptr; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only*, present only// if V models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")bool *trailing_empty_* = false; // *exposition only*public:using iterator_concept = conditional_t<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>, forward_iterator_tag, input_iterator_tag>; using iterator_category = input_iterator_tag; // present only if *Base*// models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")// [[range.lazy.split.outer.value]](#range.lazy.split.outer.value "25.7.16.4 Class lazy_split_view::outer-iterator::value_type"), class lazy_split_view::*outer-iterator*::value_typestruct value_type; using difference_type = range_difference_t<*Base*>; *outer-iterator*() = default; constexpr explicit *outer-iterator*(*Parent*& parent)requires (<*Base*>); constexpr *outer-iterator*(*Parent*& parent, iterator_t<*Base*> current)requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr *outer-iterator*(*outer-iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr value_type operator*() const; constexpr *outer-iterator*& operator++(); constexpr decltype(auto) operator++(int) {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>) {auto tmp = *this; ++*this; return tmp; } else++*this; }friend constexpr bool operator==(const *outer-iterator*& x, const *outer-iterator*& y)requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr bool operator==(const *outer-iterator*& x, default_sentinel_t); };}
|
||
|
||
[1](#range.lazy.split.outer-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8016)
|
||
|
||
Many of the specifications in [[range.lazy.split]](#range.lazy.split "25.7.16 Lazy split view") refer to the notional member*current* of *outer-iterator*[.](#range.lazy.split.outer-1.sentence-1)
|
||
|
||
*current* is equivalent to *current_* if V models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"), and **parent_*->*current_* otherwise[.](#range.lazy.split.outer-1.sentence-2)
|
||
|
||
[ð](#lib:lazy_split_view::outer-iterator,constructor)
|
||
|
||
`constexpr explicit outer-iterator(Parent& parent)
|
||
requires (<Base>);
|
||
`
|
||
|
||
[2](#range.lazy.split.outer-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8029)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent)[.](#range.lazy.split.outer-2.sentence-1)
|
||
|
||
[ð](#lib:lazy_split_view::outer-iterator,constructor_)
|
||
|
||
`constexpr outer-iterator(Parent& parent, iterator_t<Base> current)
|
||
requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[3](#range.lazy.split.outer-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8041)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent) and *current_* with std::move(current)[.](#range.lazy.split.outer-3.sentence-1)
|
||
|
||
[ð](#lib:lazy_split_view::outer-iterator,constructor__)
|
||
|
||
`constexpr outer-iterator(outer-iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[4](#range.lazy.split.outer-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8054)
|
||
|
||
*Effects*: Initializes *parent_* with i.*parent_*,*current_* with std::move(i.*current_*), and*trailing_empty_* with i.*trailing_empty_*[.](#range.lazy.split.outer-4.sentence-1)
|
||
|
||
[ð](#lib:operator*,lazy_split_view::outer-iterator)
|
||
|
||
`constexpr value_type operator*() const;
|
||
`
|
||
|
||
[5](#range.lazy.split.outer-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8067)
|
||
|
||
*Effects*: Equivalent to: return value_type{*this};
|
||
|
||
[ð](#lib:operator++,lazy_split_view::outer-iterator)
|
||
|
||
`constexpr outer-iterator& operator++();
|
||
`
|
||
|
||
[6](#range.lazy.split.outer-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8078)
|
||
|
||
*Effects*: Equivalent to:const auto end = ranges::end(*parent_*->*base_*);if (*current* == end) {*trailing_empty_* = false; return *this;}const auto [pbegin, pend] = subrange{*parent_*->*pattern_*};if (pbegin == pend) ++*current*;else if constexpr ([*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]")<Pattern>) {*current* = ranges::find(std::move(*current*), end, *pbegin); if (*current* != end) {++*current*; if (*current* == end)*trailing_empty_* = true; }}else {do {auto [b, p] = ranges::mismatch(*current*, end, pbegin, pend); if (p == pend) {*current* = b; if (*current* == end)*trailing_empty_* = true; break; // The pattern matched; skip it}} while (++*current* != end);}return *this;
|
||
|
||
[ð](#lib:operator==,lazy_split_view::outer-iterator)
|
||
|
||
`friend constexpr bool operator==(const outer-iterator& x, const outer-iterator& y)
|
||
requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[7](#range.lazy.split.outer-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8119)
|
||
|
||
*Effects*: Equivalent to:return x.*current_* == y.*current_* && x.*trailing_empty_* == y.*trailing_empty_*;
|
||
|
||
[ð](#lib:operator==,lazy_split_view::outer-iterator_)
|
||
|
||
`friend constexpr bool operator==(const outer-iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[8](#range.lazy.split.outer-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8133)
|
||
|
||
*Effects*: Equivalent to:return x.*current* == ranges::end(x.*parent_*->*base_*) && !x.*trailing_empty_*;
|
||
|
||
#### [25.7.16.4](#range.lazy.split.outer.value) Class lazy_split_view::*outer-iterator*::value_type [[range.lazy.split.outer.value]](range.lazy.split.outer.value)
|
||
|
||
[ð](#lib:lazy_split_view::outer-iterator::value_type)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> || [*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]")<Pattern>)template<bool Const>struct lazy_split_view<V, Pattern>::*outer-iterator*<Const>::value_type : view_interface<value_type> {private:*outer-iterator* *i_* = *outer-iterator*(); // *exposition only*constexpr explicit value_type(*outer-iterator* i); // *exposition only*public:constexpr *inner-iterator*<Const> begin() const; constexpr default_sentinel_t end() const noexcept; };}
|
||
|
||
[ð](#lib:lazy_split_view::outer-iterator::value_type,constructor)
|
||
|
||
`constexpr explicit value_type(outer-iterator i);
|
||
`
|
||
|
||
[1](#range.lazy.split.outer.value-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8171)
|
||
|
||
*Effects*: Initializes *i_* with std::move(i)[.](#range.lazy.split.outer.value-1.sentence-1)
|
||
|
||
[ð](#lib:begin,lazy_split_view::outer-iterator::value_type)
|
||
|
||
`constexpr inner-iterator<Const> begin() const;
|
||
`
|
||
|
||
[2](#range.lazy.split.outer.value-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8182)
|
||
|
||
*Effects*: Equivalent to: return *inner-iterator*<Const>{*i_*};
|
||
|
||
[ð](#lib:end,lazy_split_view::outer-iterator::value_type)
|
||
|
||
`constexpr default_sentinel_t end() const noexcept;
|
||
`
|
||
|
||
[3](#range.lazy.split.outer.value-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8193)
|
||
|
||
*Effects*: Equivalent to: return default_sentinel;
|
||
|
||
#### [25.7.16.5](#range.lazy.split.inner) Class template lazy_split_view::*inner-iterator* [[range.lazy.split.inner]](range.lazy.split.inner)
|
||
|
||
[ð](#lib:lazy_split_view::inner-iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> &&([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> || [*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]")<Pattern>)template<bool Const>struct lazy_split_view<V, Pattern>::*inner-iterator* {private:using *Base* = *maybe-const*<Const, V>; // *exposition only**outer-iterator*<Const> *i_* = *outer-iterator*<Const>(); // *exposition only*bool *incremented_* = false; // *exposition only*public:using iterator_concept = typename *outer-iterator*<Const>::iterator_concept; using iterator_category = *see below*; // present only if *Base*// models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")using value_type = range_value_t<*Base*>; using difference_type = range_difference_t<*Base*>; *inner-iterator*() = default; constexpr explicit *inner-iterator*(*outer-iterator*<Const> i); constexpr const iterator_t<*Base*>& base() const & noexcept; constexpr iterator_t<*Base*> base() && requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>; constexpr decltype(auto) operator*() const { return **i_*.*current*; }constexpr *inner-iterator*& operator++(); constexpr decltype(auto) operator++(int) {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>) {auto tmp = *this; ++*this; return tmp; } else++*this; }friend constexpr bool operator==(const *inner-iterator*& x, const *inner-iterator*& y)requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; friend constexpr bool operator==(const *inner-iterator*& x, default_sentinel_t); friend constexpr decltype(auto) iter_move(const *inner-iterator*& i)noexcept(noexcept(ranges::iter_move(i.*i_*.*current*))) {return ranges::iter_move(i.*i_*.*current*); }friend constexpr void iter_swap(const *inner-iterator*& x, const *inner-iterator*& y)noexcept(noexcept(ranges::iter_swap(x.*i_*.*current*, y.*i_*.*current*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.lazy.split.inner-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8257)
|
||
|
||
If *Base* does not model [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") there is no member iterator_category[.](#range.lazy.split.inner-1.sentence-1)
|
||
|
||
Otherwise, the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category denotes:
|
||
|
||
- [(1.1)](#range.lazy.split.inner-1.1)
|
||
|
||
forward_iterator_tag ifiterator_traits<iterator_t<*Base*>>::iterator_category models[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<forward_iterator_tag>;
|
||
|
||
- [(1.2)](#range.lazy.split.inner-1.2)
|
||
|
||
otherwise, iterator_traits<iterator_t<*Base*>>::iterator_category[.](#range.lazy.split.inner-1.sentence-2)
|
||
|
||
[ð](#lib:lazy_split_view::inner-iterator,constructor)
|
||
|
||
`constexpr explicit inner-iterator(outer-iterator<Const> i);
|
||
`
|
||
|
||
[2](#range.lazy.split.inner-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8275)
|
||
|
||
*Effects*: Initializes *i_* with std::move(i)[.](#range.lazy.split.inner-2.sentence-1)
|
||
|
||
[ð](#lib:base,lazy_split_view::inner-iterator)
|
||
|
||
`constexpr const iterator_t<Base>& base() const & noexcept;
|
||
`
|
||
|
||
[3](#range.lazy.split.inner-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8286)
|
||
|
||
*Effects*: Equivalent to: return *i_*.*current*;
|
||
|
||
[ð](#lib:base,lazy_split_view::inner-iterator_)
|
||
|
||
`constexpr iterator_t<Base> base() && requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[4](#range.lazy.split.inner-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8297)
|
||
|
||
*Effects*: Equivalent to: return std::move(*i_*.*current*);
|
||
|
||
[ð](#lib:operator++,lazy_split_view::inner-iterator)
|
||
|
||
`constexpr inner-iterator& operator++();
|
||
`
|
||
|
||
[5](#range.lazy.split.inner-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8308)
|
||
|
||
*Effects*: Equivalent to:*incremented_* = true;if constexpr (<*Base*>) {if constexpr (Pattern::size() == 0) {return *this; }}++*i_*.*current*;return *this;
|
||
|
||
[ð](#lib:operator==,lazy_split_view::inner-iterator)
|
||
|
||
`friend constexpr bool operator==(const inner-iterator& x, const inner-iterator& y)
|
||
requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[6](#range.lazy.split.inner-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8330)
|
||
|
||
*Effects*: Equivalent to: return x.*i_*.*current* == y.*i_*.*current*;
|
||
|
||
[ð](#lib:operator==,lazy_split_view::inner-iterator_)
|
||
|
||
`friend constexpr bool operator==(const inner-iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[7](#range.lazy.split.inner-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8341)
|
||
|
||
*Effects*: Equivalent to:auto [pcur, pend] = subrange{x.*i_*.*parent_*->*pattern_*};auto end = ranges::end(x.*i_*.*parent_*->*base_*);if constexpr ([*tiny-range*](#concept:tiny-range "25.7.16.2 Class template lazy_split_view [range.lazy.split.view]")<Pattern>) {const auto & cur = x.*i_*.*current*; if (cur == end) return true; if (pcur == pend) return x.*incremented_*; return *cur == *pcur;} else {auto cur = x.*i_*.*current*; if (cur == end) return true; if (pcur == pend) return x.*incremented_*; do {if (*cur != *pcur) return false; if (++pcur == pend) return true; } while (++cur != end); return false;}
|
||
|
||
[ð](#lib:iter_swap,lazy_split_view::inner-iterator)
|
||
|
||
`friend constexpr void iter_swap(const inner-iterator& x, const inner-iterator& y)
|
||
noexcept(noexcept(ranges::iter_swap(x.i_.current, y.i_.current)))
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[8](#range.lazy.split.inner-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8373)
|
||
|
||
*Effects*: Equivalent toranges::iter_swap(x.*i_*.*current*, y.*i_*.*current*)[.](#range.lazy.split.inner-8.sentence-1)
|
||
|
||
### [25.7.17](#range.split) Split view [[range.split]](range.split)
|
||
|
||
#### [25.7.17.1](#range.split.overview) Overview [[range.split.overview]](range.split.overview)
|
||
|
||
[1](#range.split.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8383)
|
||
|
||
split_view takes a view and a delimiter, and
|
||
splits the view into subranges on the delimiter[.](#range.split.overview-1.sentence-1)
|
||
|
||
The delimiter can be a single element or a view of elements[.](#range.split.overview-1.sentence-2)
|
||
|
||
[2](#range.split.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8388)
|
||
|
||
The name views::split denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.split.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F,
|
||
the expression views::split(E, F) is expression-equivalent tosplit_view(E, F)[.](#range.split.overview-2.sentence-2)
|
||
|
||
[3](#range.split.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8395)
|
||
|
||
[*Example [1](#range.split.overview-example-1)*: string str{"the quick brown fox"};for (auto word : views::split(str, ' ')) { cout << string_view(word) << '*';}// The above prints the*quick*brown*fox* â *end example*]
|
||
|
||
#### [25.7.17.2](#range.split.view) Class template split_view [[range.split.view]](range.split.view)
|
||
|
||
[ð](#lib:split_view)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>class split_view : public view_interface<split_view<V, Pattern>> {private: V *base_* = V(); // *exposition only* Pattern *pattern_* = Pattern(); // *exposition only*// [[range.split.iterator]](#range.split.iterator "25.7.17.3 Class split_view::iterator"), class split_view::*iterator*struct *iterator*; // *exposition only*// [[range.split.sentinel]](#range.split.sentinel "25.7.17.4 Class split_view::sentinel"), class split_view::*sentinel*struct *sentinel*; // *exposition only*public: split_view()requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pattern> = default; constexpr explicit split_view(V base, Pattern pattern); template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") R>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<V, views::all_t<R>> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<Pattern, single_view<range_value_t<R>>>constexpr explicit split_view(R&& r, range_value_t<R> e); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr *iterator* begin(); constexpr auto end() {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>) {return *iterator*{*this, ranges::end(*base_*), {}}; } else {return *sentinel*{*this}; }}constexpr subrange<iterator_t<V>> *find-next*(iterator_t<V>); // *exposition only*}; template<class R, class P> split_view(R&&, P&&) -> split_view<views::all_t<R>, views::all_t<P>>; template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") R> split_view(R&&, range_value_t<R>)-> split_view<views::all_t<R>, single_view<range_value_t<R>>>;}
|
||
|
||
[ð](#lib:split_view,constructor)
|
||
|
||
`constexpr explicit split_view(V base, Pattern pattern);
|
||
`
|
||
|
||
[1](#range.split.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8466)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base), and*pattern_* with std::move(pattern)[.](#range.split.view-1.sentence-1)
|
||
|
||
[ð](#lib:split_view,constructor_)
|
||
|
||
`template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") R>
|
||
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<V, views::all_t<R>> &&
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<Pattern, single_view<range_value_t<R>>>
|
||
constexpr explicit split_view(R&& r, range_value_t<R> e);
|
||
`
|
||
|
||
[2](#range.split.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8481)
|
||
|
||
*Effects*: Initializes *base_* with views::all(std::forward<R>(r)), and*pattern_* with views::single(std::move(e))[.](#range.split.view-2.sentence-1)
|
||
|
||
[ð](#lib:begin,split_view)
|
||
|
||
`constexpr iterator begin();
|
||
`
|
||
|
||
[3](#range.split.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8493)
|
||
|
||
*Returns*: {*this, ranges::begin(*base_*), *find-next*(ranges::begin(*base_*))}[.](#range.split.view-3.sentence-1)
|
||
|
||
[4](#range.split.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8497)
|
||
|
||
*Remarks*: In order to provide the amortized constant time complexity
|
||
required by the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept,
|
||
this function caches the result within the split_view for use on subsequent calls[.](#range.split.view-4.sentence-1)
|
||
|
||
[ð](#lib:find-next,split_view)
|
||
|
||
`constexpr subrange<iterator_t<V>> find-next(iterator_t<V> it);
|
||
`
|
||
|
||
[5](#range.split.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8511)
|
||
|
||
*Effects*: Equivalent to:auto [b, e] = ranges::search(subrange(it, ranges::end(*base_*)), *pattern_*);if (b != ranges::end(*base_*) && ranges::empty(*pattern_*)) {++b; ++e;}return {b, e};
|
||
|
||
#### [25.7.17.3](#range.split.iterator) Class split_view::*iterator* [[range.split.iterator]](range.split.iterator)
|
||
|
||
[ð](#lib:split_view::iterator)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>class split_view<V, Pattern>::*iterator* {private: split_view* *parent_* = nullptr; // *exposition only* iterator_t<V> *cur_* = iterator_t<V>(); // *exposition only* subrange<iterator_t<V>> *next_* = subrange<iterator_t<V>>(); // *exposition only*bool *trailing_empty_* = false; // *exposition only*public:using iterator_concept = forward_iterator_tag; using iterator_category = input_iterator_tag; using value_type = subrange<iterator_t<V>>; using difference_type = range_difference_t<V>; *iterator*() = default; constexpr *iterator*(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next); constexpr iterator_t<V> base() const; constexpr value_type operator*() const; constexpr *iterator*& operator++(); constexpr *iterator* operator++(int); friend constexpr bool operator==(const *iterator*& x, const *iterator*& y); };}
|
||
|
||
[ð](#lib:split_view::iterator,constructor)
|
||
|
||
`constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next);
|
||
`
|
||
|
||
[1](#range.split.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8565)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent),*cur_* with std::move(current), and*next_* with std::move(next)[.](#range.split.iterator-1.sentence-1)
|
||
|
||
[ð](#lib:base,split_view::iterator)
|
||
|
||
`constexpr iterator_t<V> base() const;
|
||
`
|
||
|
||
[2](#range.split.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8578)
|
||
|
||
*Effects*: Equivalent to: return *cur_*;
|
||
|
||
[ð](#lib:operator*,split_view::iterator)
|
||
|
||
`constexpr value_type operator*() const;
|
||
`
|
||
|
||
[3](#range.split.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8589)
|
||
|
||
*Effects*: Equivalent to: return {*cur_*, *next_*.begin()};
|
||
|
||
[ð](#lib:operator++,split_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[4](#range.split.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8600)
|
||
|
||
*Effects*: Equivalent to:*cur_* = *next_*.begin();if (*cur_* != ranges::end(*parent_*->*base_*)) {*cur_* = *next_*.end(); if (*cur_* == ranges::end(*parent_*->*base_*)) {*trailing_empty_* = true; *next_* = {*cur_*, *cur_*}; } else {*next_* = *parent_*->*find-next*(*cur_*); }} else {*trailing_empty_* = false;}return *this;
|
||
|
||
[ð](#lib:operator++,split_view::iterator_)
|
||
|
||
`constexpr iterator operator++(int);
|
||
`
|
||
|
||
[5](#range.split.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8626)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator==,split_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y);
|
||
`
|
||
|
||
[6](#range.split.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8642)
|
||
|
||
*Effects*: Equivalent to:return x.*cur_* == y.*cur_* && x.*trailing_empty_* == y.*trailing_empty_*;
|
||
|
||
#### [25.7.17.4](#range.split.sentinel) Class split_view::*sentinel* [[range.split.sentinel]](range.split.sentinel)
|
||
|
||
[ð](#lib:split_view::sentinel)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [view](range.view#concept:view "25.4.5 Views [range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5 Concept indirectly_comparable [alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>struct split_view<V, Pattern>::*sentinel* {private: sentinel_t<V> *end_* = sentinel_t<V>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(split_view& parent); friend constexpr bool operator==(const *iterator*& x, const *sentinel*& y); };}
|
||
|
||
[ð](#lib:split_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(split_view& parent);
|
||
`
|
||
|
||
[1](#range.split.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8677)
|
||
|
||
*Effects*: Initializes *end_* with ranges::end(parent.*base_*)[.](#range.split.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:operator==,split_view::sentinel)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
||
`
|
||
|
||
[2](#range.split.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8688)
|
||
|
||
*Effects*: Equivalent to: return x.*cur_* == y.*end_* && !x.*trailing_empty_*;
|
||
|
||
### [25.7.18](#range.concat) Concat view [[range.concat]](range.concat)
|
||
|
||
#### [25.7.18.1](#range.concat.overview) Overview [[range.concat.overview]](range.concat.overview)
|
||
|
||
[1](#range.concat.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8697)
|
||
|
||
concat_view presents a view that concatenates all the underlying ranges[.](#range.concat.overview-1.sentence-1)
|
||
|
||
[2](#range.concat.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8700)
|
||
|
||
The name views::concat denotes
|
||
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))[.](#range.concat.overview-2.sentence-1)
|
||
|
||
Given a pack of subexpressions Es...,
|
||
the expression views::concat(Es...) is expression-equivalent to
|
||
|
||
- [(2.1)](#range.concat.overview-2.1)
|
||
|
||
views::all(Es...) if Es is a pack with only one element
|
||
whose type models [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]"),
|
||
|
||
- [(2.2)](#range.concat.overview-2.2)
|
||
|
||
otherwise, concat_view(Es...)[.](#range.concat.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.concat.overview-example-1)*: vector<int> v1{1, 2, 3}, v2{4, 5}, v3{};
|
||
array a{6, 7, 8};auto s = views::single(9);for (auto&& i : views::concat(v1, v2, v3, a, s)) { print("{} ", i); // prints 1 2 3 4 5 6 7 8 9} â *end example*]
|
||
|
||
#### [25.7.18.2](#range.concat.view) Class template concat_view [[range.concat.view]](range.concat.view)
|
||
|
||
[ð](#lib:concat_view)
|
||
|
||
namespace std::ranges {template<class... Rs>using *concat-reference-t* = common_reference_t<range_reference_t<Rs>...>; // *exposition only*template<class... Rs>using *concat-value-t* = common_type_t<range_value_t<Rs>...>; // *exposition only*template<class... Rs>using *concat-rvalue-reference-t* = // *exposition only* common_reference_t<range_rvalue_reference_t<Rs>...>; template<class... Rs>concept [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_view [range.concat.view]") = *see below*; // *exposition only*template<class... Rs>concept [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]") = *see below*; // *exposition only*template<bool Const, class... Rs>concept [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]") = *see below*; // *exposition only*template<bool Const, class... Rs>concept [*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]") = *see below*; // *exposition only*template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0) &&[*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<Views...>class concat_view : public view_interface<concat_view<Views...>> { tuple<Views...> *views_*; // *exposition only*// [[range.concat.iterator]](#range.concat.iterator "25.7.18.3 Class concat_view::iterator"), class template concat_view::*iterator*template<bool> class *iterator*; // *exposition only*public:constexpr concat_view() = default; constexpr explicit concat_view(Views... views); constexpr *iterator*<false> begin() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...)); constexpr *iterator*<true> begin() constrequires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) && [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<const Views...>; constexpr auto end() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...)); constexpr auto end() constrequires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) && [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<const Views...>; constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Views> && ...); constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const Views> && ...); }; template<class... R> concat_view(R&&...) -> concat_view<views::all_t<R>...>;}
|
||
|
||
[ð](#concept:concat-indirectly-readable)
|
||
|
||
`template<class... Rs>
|
||
concept [concat-indirectly-readable](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_view [range.concat.view]") = see below; // exposition only
|
||
`
|
||
|
||
[1](#range.concat.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8780)
|
||
|
||
The exposition-only [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_view [range.concat.view]") concept
|
||
is equivalent to:template<class Ref, class RRef, class It>concept [*concat-indirectly-readable-impl*](#concept:concat-indirectly-readable-impl "25.7.18.2 Class template concat_view [range.concat.view]") = // *exposition only*requires (const It it) {{ *it } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<Ref>; { ranges::iter_move(it) } -> [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<RRef>; };
|
||
|
||
template<class... Rs>concept [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_view [range.concat.view]") = // *exposition only*[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_reference_with [concept.commonref]")<*concat-reference-t*<Rs...>&&, *concat-value-t*<Rs...>&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_reference_with [concept.commonref]")<*concat-reference-t*<Rs...>&&, *concat-rvalue-reference-t*<Rs...>&&> &&[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_reference_with [concept.commonref]")<*concat-rvalue-reference-t*<Rs...>&&, *concat-value-t*<Rs...> const&> &&([*concat-indirectly-readable-impl*](#concept:concat-indirectly-readable-impl "25.7.18.2 Class template concat_view [range.concat.view]")<*concat-reference-t*<Rs...>, *concat-rvalue-reference-t*<Rs...>,
|
||
iterator_t<Rs>> && ...);
|
||
|
||
[ð](#concept:concatable)
|
||
|
||
`template<class... Rs>
|
||
concept [concatable](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]") = see below; // exposition only
|
||
`
|
||
|
||
[2](#range.concat.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8811)
|
||
|
||
The exposition-only [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]") concept is equivalent to:template<class... Rs>concept [*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]") = requires { // *exposition only*typename *concat-reference-t*<Rs...>; typename *concat-value-t*<Rs...>; typename *concat-rvalue-reference-t*<Rs...>; } && [*concat-indirectly-readable*](#concept:concat-indirectly-readable "25.7.18.2 Class template concat_view [range.concat.view]")<Rs...>;
|
||
|
||
[ð](#concept:concat-is-random-access)
|
||
|
||
`template<bool Const, class... Rs>
|
||
concept [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]") = see below; // exposition only
|
||
`
|
||
|
||
[3](#range.concat.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8829)
|
||
|
||
Let Fs be the pack that consists of all elements of Rs except the last element,
|
||
then *concat-is-random-access* is equivalent to:template<bool Const, class... Rs>concept [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]") = // *exposition only*[*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Rs...> &&([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Fs>> && ...);
|
||
|
||
[ð](#concept:concat-is-bidirectional)
|
||
|
||
`template<bool Const, class... Rs>
|
||
concept [concat-is-bidirectional](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]") = see below; // exposition only
|
||
`
|
||
|
||
[4](#range.concat.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8848)
|
||
|
||
Let Fs be the pack that consists of all elements of Rs except the last element,
|
||
then *concat-is-bidirectional* is equivalent to:template<bool Const, class... Rs>concept [*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]") = // *exposition only*[*all-bidirectional*](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Rs...> &&([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Fs>> && ...);
|
||
|
||
[ð](#lib:concat_view,constructor)
|
||
|
||
`constexpr explicit concat_view(Views... views);
|
||
`
|
||
|
||
[5](#range.concat.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8867)
|
||
|
||
*Effects*: Initializes *views_* with std::move(views)...[.](#range.concat.view-5.sentence-1)
|
||
|
||
[ð](#lib:begin,concat_view)
|
||
|
||
`constexpr iterator<false> begin() requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...));
|
||
constexpr iterator<true> begin() const
|
||
requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) && [concatable](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<const Views...>;
|
||
`
|
||
|
||
[6](#range.concat.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8880)
|
||
|
||
*Effects*: Let *is-const* betrue for the const-qualified overload, andfalse otherwise[.](#range.concat.view-6.sentence-1)
|
||
|
||
Equivalent to:*iterator*<*is-const*> it(this, in_place_index<0>, ranges::begin(std::get<0>(*views_*)));
|
||
it.template *satisfy*<0>();return it;
|
||
|
||
[ð](#lib:end,concat_view)
|
||
|
||
`constexpr auto end() requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...));
|
||
constexpr auto end() const
|
||
requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) && [concatable](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<const Views...>;
|
||
`
|
||
|
||
[7](#range.concat.view-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8901)
|
||
|
||
*Effects*: Let *is-const* betrue for the const-qualified overload, andfalse otherwise[.](#range.concat.view-7.sentence-1)
|
||
|
||
Equivalent to:constexpr auto N = sizeof...(Views);if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<*is-const*, Views...[N - 1]>>) {return *iterator*<*is-const*>(this, in_place_index<N - 1>,
|
||
ranges::end(std::get<N - 1>(*views_*)));} else {return default_sentinel;}
|
||
|
||
[ð](#lib:size,concat_view)
|
||
|
||
`constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Views> && ...);
|
||
constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const Views> && ...);
|
||
`
|
||
|
||
[8](#range.concat.view-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8925)
|
||
|
||
*Effects*: Equivalent to:return apply([](auto... sizes) {using CT = *make-unsigned-like-t*<common_type_t<decltype(sizes)...>>; return (CT(sizes) + ...); }, *tuple-transform*(ranges::size, *views_*));
|
||
|
||
#### [25.7.18.3](#range.concat.iterator) Class concat_view::*iterator* [[range.concat.iterator]](range.concat.iterator)
|
||
|
||
[ð](#lib:iterator,concat_view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0) &&[*concatable*](#concept:concatable "25.7.18.2 Class template concat_view [range.concat.view]")<Views...>template<bool Const>class concat_view<Views...>::*iterator* {public:using iterator_category = *see below*; // not always presentusing iterator_concept = *see below*; using value_type = *concat-value-t*<*maybe-const*<Const, Views>...>; using difference_type = common_type_t<range_difference_t<*maybe-const*<Const, Views>>...>; private:using *base-iter* = // *exposition only* variant<iterator_t<*maybe-const*<Const, Views>>...>; *maybe-const*<Const, concat_view>* *parent_* = nullptr; // *exposition only**base-iter* *it_*; // *exposition only*template<size_t N>constexpr void *satisfy*(); // *exposition only*template<size_t N>constexpr void *prev*(); // *exposition only*template<size_t N>constexpr void *advance-fwd*(difference_type offset, // *exposition only* difference_type steps); template<size_t N>constexpr void *advance-bwd*(difference_type offset, // *exposition only* difference_type steps); template<class... Args>constexpr explicit *iterator*(*maybe-const*<Const, concat_view>* parent, // *exposition only* Args&&... args)requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<*base-iter*, Args&&...>; public:*iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...); constexpr decltype(auto) operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int)requires [*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator--()requires [*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; constexpr *iterator* operator--(int)requires [*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; constexpr *iterator*& operator+=(difference_type n)requires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; constexpr *iterator*& operator-=(difference_type n)requires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; constexpr decltype(auto) operator[](difference_type n) constrequires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires ([equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<*maybe-const*<Const, Views>>> && ...); friend constexpr bool operator==(const *iterator*& it, default_sentinel_t); friend constexpr bool operator<(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr bool operator>(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr bool operator<=(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr bool operator>=(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr auto operator<=>(const *iterator*& x, const *iterator*& y)requires ([*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> &&([three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<*maybe-const*<Const, Views>>> && ...)); friend constexpr *iterator* operator+(const *iterator*& it, difference_type n)requires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; friend constexpr *iterator* operator+(difference_type n, const *iterator*& it)requires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; friend constexpr *iterator* operator-(const *iterator*& it, difference_type n)requires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; friend constexpr difference_type operator-(const *iterator*& x, const *iterator*& y)requires [*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>; friend constexpr difference_type operator-(const *iterator*& x, default_sentinel_t)requires *see below*; friend constexpr difference_type operator-(default_sentinel_t, const *iterator*& x)requires *see below*; friend constexpr decltype(auto) iter_move(const *iterator*& it) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y) noexcept(*see below*)requires *see below*; };}
|
||
|
||
[1](#range.concat.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9035)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.concat.iterator-1.1)
|
||
|
||
If[*concat-is-random-access*](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...> is modeled,
|
||
then iterator_concept denotes random_access_iterator_tag[.](#range.concat.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.concat.iterator-1.2)
|
||
|
||
Otherwise, if[*concat-is-bidirectional*](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...> is modeled,
|
||
then iterator_concept denotes bidirectional_iterator_tag[.](#range.concat.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.concat.iterator-1.3)
|
||
|
||
Otherwise, if[*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is modeled,
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.concat.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.concat.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.concat.iterator-1.4.sentence-1)
|
||
|
||
[2](#range.concat.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9054)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if[*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is modeled[.](#range.concat.iterator-2.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
|
||
- [(2.1)](#range.concat.iterator-2.1)
|
||
|
||
Ifis_reference_v<*concat-reference-t*<*maybe-const*<Const, Views>...>> is false,
|
||
then iterator_category denotes input_iterator_tag[.](#range.concat.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.concat.iterator-2.2)
|
||
|
||
Otherwise,
|
||
let Cs denote the pack of typesiterator_traits<iterator_t<*maybe-const*<Const, Views>>>::iterator_category...[.](#range.concat.iterator-2.2.sentence-1)
|
||
|
||
* [(2.2.1)](#range.concat.iterator-2.2.1)
|
||
|
||
If([derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<Cs, random_access_iterator_tag> && ...) && *concat-is-random-access*<Const, Views...> is true,iterator_category denotes random_access_iterator_tag[.](#range.concat.iterator-2.2.1.sentence-1)
|
||
|
||
* [(2.2.2)](#range.concat.iterator-2.2.2)
|
||
|
||
Otherwise, if([derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<Cs, bidirectional_iterator_tag> && ...) && *concat-is-bidirectional*<Const, Views...> is true,iterator_category denotes bidirectional_iterator_tag[.](#range.concat.iterator-2.2.2.sentence-1)
|
||
|
||
* [(2.2.3)](#range.concat.iterator-2.2.3)
|
||
|
||
Otherwise, if([derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<Cs, forward_iterator_tag> && ...) is true,iterator_category denotes forward_iterator_tag[.](#range.concat.iterator-2.2.3.sentence-1)
|
||
|
||
* [(2.2.4)](#range.concat.iterator-2.2.4)
|
||
|
||
Otherwise, iterator_category denotes input_iterator_tag[.](#range.concat.iterator-2.2.4.sentence-1)
|
||
|
||
[ð](#lib:satisfy,concat_view::iterator)
|
||
|
||
`template<size_t N>
|
||
constexpr void satisfy();
|
||
`
|
||
|
||
[3](#range.concat.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9100)
|
||
|
||
*Effects*: Equivalent to:if constexpr (N < (sizeof...(Views) - 1)) {if (std::get<N>(*it_*) == ranges::end(std::get<N>(*parent_*->*views_*))) {*it_*.template emplace<N + 1>(ranges::begin(std::get<N + 1>(*parent_*->*views_*))); *satisfy*<N + 1>(); }}
|
||
|
||
[ð](#lib:prev,concat_view::iterator)
|
||
|
||
`template<size_t N>
|
||
constexpr void prev();
|
||
`
|
||
|
||
[4](#range.concat.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9120)
|
||
|
||
*Effects*: Equivalent to:if constexpr (N == 0) {--std::get<0>(*it_*);} else {if (std::get<N>(*it_*) == ranges::begin(std::get<N>(*parent_*->*views_*))) {*it_*.template emplace<N - 1>(ranges::end(std::get<N - 1>(*parent_*->*views_*))); *prev*<N - 1>(); } else {--std::get<N>(*it_*); }}
|
||
|
||
[ð](#lib:advance-fwd,concat_view::iterator)
|
||
|
||
`template<size_t N>
|
||
constexpr void advance-fwd(difference_type offset, difference_type steps);
|
||
`
|
||
|
||
[5](#range.concat.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9144)
|
||
|
||
*Effects*: Equivalent to:using underlying_diff_type = iter_difference_t<variant_alternative_t<N, *base-iter*>>;if constexpr (N == sizeof...(Views) - 1) { std::get<N>(*it_*) += static_cast<underlying_diff_type>(steps);} else {auto n_size = ranges::distance(std::get<N>(*parent_*->*views_*)); if (offset + steps < n_size) { std::get<N>(*it_*) += static_cast<underlying_diff_type>(steps); } else {*it_*.template emplace<N + 1>(ranges::begin(std::get<N + 1>(*parent_*->*views_*))); *advance-fwd*<N + 1>(0, offset + steps - n_size); }}
|
||
|
||
[ð](#lib:advance-bwd,concat_view::iterator)
|
||
|
||
`template<size_t N>
|
||
constexpr void advance-bwd(difference_type offset, difference_type steps);
|
||
`
|
||
|
||
[6](#range.concat.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9170)
|
||
|
||
*Effects*: Equivalent to:using underlying_diff_type = iter_difference_t<variant_alternative_t<N, *base-iter*>>;if constexpr (N == 0) { std::get<N>(*it_*) -= static_cast<underlying_diff_type>(steps);} else {if (offset >= steps) { std::get<N>(*it_*) -= static_cast<underlying_diff_type>(steps); } else {auto prev_size = ranges::distance(std::get<N - 1>(*parent_*->*views_*)); *it_*.template emplace<N - 1>(ranges::end(std::get<N - 1>(*parent_*->*views_*))); *advance-bwd*<N - 1>(prev_size, steps - offset); }}
|
||
|
||
[ð](#lib:concat_view::iterator,constructor)
|
||
|
||
`template<class... Args>
|
||
constexpr explicit iterator(maybe-const<Const, concat_view>* parent,
|
||
Args&&... args)
|
||
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<base-iter, Args&&...>;
|
||
`
|
||
|
||
[7](#range.concat.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9198)
|
||
|
||
*Effects*: Initializes *parent_* with parent, and
|
||
initializes *it_* with std::forward<Args>(args)...[.](#range.concat.iterator-7.sentence-1)
|
||
|
||
[ð](#lib:concat_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> it)
|
||
requires Const &&
|
||
([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...);
|
||
`
|
||
|
||
[8](#range.concat.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9212)
|
||
|
||
*Preconditions*: it.*it_*.valueless_by_exception() is false[.](#range.concat.iterator-8.sentence-1)
|
||
|
||
[9](#range.concat.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9216)
|
||
|
||
*Effects*: Initializes *parent_* with it.*parent_*, and
|
||
let i be it.*it_*.index(),
|
||
initializes *it_* with*base-iter*(in_place_index<i>, std::get<i>(std::move(it.*it_*)))[.](#range.concat.iterator-9.sentence-1)
|
||
|
||
[ð](#lib:operator*,concat_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator*() const;
|
||
`
|
||
|
||
[10](#range.concat.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9230)
|
||
|
||
*Preconditions*: *it_*.valueless_by_exception() is false[.](#range.concat.iterator-10.sentence-1)
|
||
|
||
[11](#range.concat.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9234)
|
||
|
||
*Effects*: Equivalent to:using reference = *concat-reference-t*<*maybe-const*<Const, Views>...>;return std::visit([](auto&& it) -> reference { return *it; }, *it_*);
|
||
|
||
[ð](#lib:operator++,concat_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[12](#range.concat.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9250)
|
||
|
||
*Preconditions*: *it_*.valueless_by_exception() is false[.](#range.concat.iterator-12.sentence-1)
|
||
|
||
[13](#range.concat.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9254)
|
||
|
||
*Effects*: Let i be *it_*.index()[.](#range.concat.iterator-13.sentence-1)
|
||
|
||
Equivalent to:++std::get<i>(*it_*);*satisfy*<i>();return *this;
|
||
|
||
[ð](#lib:operator++,concat_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[14](#range.concat.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9271)
|
||
|
||
*Effects*: Equivalent to:++*this;
|
||
|
||
[ð](#lib:operator++,concat_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int)
|
||
requires [all-forward](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[15](#range.concat.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9286)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,concat_view::iterator)
|
||
|
||
`constexpr iterator& operator--()
|
||
requires [concat-is-bidirectional](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[16](#range.concat.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9303)
|
||
|
||
*Preconditions*: *it_*.valueless_by_exception() is false[.](#range.concat.iterator-16.sentence-1)
|
||
|
||
[17](#range.concat.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9307)
|
||
|
||
*Effects*: Let i be *it_*.index()[.](#range.concat.iterator-17.sentence-1)
|
||
|
||
Equivalent to:*prev*<i>();return *this;
|
||
|
||
[ð](#lib:operator--,concat_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int)
|
||
requires [concat-is-bidirectional](#concept:concat-is-bidirectional "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[18](#range.concat.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9324)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,concat_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type n)
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[19](#range.concat.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9341)
|
||
|
||
*Preconditions*: *it_*.valueless_by_exception() is false[.](#range.concat.iterator-19.sentence-1)
|
||
|
||
[20](#range.concat.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9345)
|
||
|
||
*Effects*: Let i be *it_*.index()[.](#range.concat.iterator-20.sentence-1)
|
||
|
||
Equivalent to:if (n > 0) {*advance-fwd*<i>(std::get<i>(*it_*) - ranges::begin(std::get<i>(*parent_*->*views_*)), n);} else if (n < 0) {*advance-bwd*<i>(std::get<i>(*it_*) - ranges::begin(std::get<i>(*parent_*->*views_*)), -n);}return *this;
|
||
|
||
[ð](#lib:operator-=,concat_view::iterator)
|
||
|
||
`constexpr iterator& operator-=(difference_type n)
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[21](#range.concat.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9366)
|
||
|
||
*Effects*: Equivalent to:*this += -n;return *this;
|
||
|
||
[ð](#lib:operator%5b%5d,concat_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator[](difference_type n) const
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[22](#range.concat.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9382)
|
||
|
||
*Effects*: Equivalent to:return *((*this) + n);
|
||
|
||
[ð](#lib:operator==,concat_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires ([equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<maybe-const<Const, Views>>> && ...);
|
||
`
|
||
|
||
[23](#range.concat.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9397)
|
||
|
||
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#range.concat.iterator-23.sentence-1)
|
||
|
||
[24](#range.concat.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9402)
|
||
|
||
*Effects*: Equivalent to:return x.*it_* == y.*it_*;
|
||
|
||
[ð](#lib:operator==,concat_view::iterator_)
|
||
|
||
`friend constexpr bool operator==(const iterator& it, default_sentinel_t);
|
||
`
|
||
|
||
[25](#range.concat.iterator-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9416)
|
||
|
||
*Preconditions*: it.*it_*.valueless_by_exception() is false[.](#range.concat.iterator-25.sentence-1)
|
||
|
||
[26](#range.concat.iterator-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9420)
|
||
|
||
*Effects*: Equivalent to:constexpr auto last_idx = sizeof...(Views) - 1;return it.*it_*.index() == last_idx && std::get<last_idx>(it.*it_*) == ranges::end(std::get<last_idx>(it.*parent_*->*views_*));
|
||
|
||
[ð](#lib:operator%3c,concat_view::iterator)
|
||
|
||
`friend constexpr bool operator<(const iterator& x, const iterator& y)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
friend constexpr bool operator>(const iterator& x, const iterator& y)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
friend constexpr bool operator<=(const iterator& x, const iterator& y)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
friend constexpr bool operator>=(const iterator& x, const iterator& y)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
||
requires ([all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> &&
|
||
([three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<maybe-const<Const, Views>>> && ...));
|
||
`
|
||
|
||
[27](#range.concat.iterator-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9446)
|
||
|
||
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#range.concat.iterator-27.sentence-1)
|
||
|
||
[28](#range.concat.iterator-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9451)
|
||
|
||
Let op be the operator[.](#range.concat.iterator-28.sentence-1)
|
||
|
||
[29](#range.concat.iterator-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9454)
|
||
|
||
*Effects*: Equivalent to:return x.*it_* op y.*it_*;
|
||
|
||
[ð](#lib:operator+,concat_view::iterator)
|
||
|
||
`friend constexpr iterator operator+(const iterator& it, difference_type n)
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[30](#range.concat.iterator-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9469)
|
||
|
||
*Effects*: Equivalent to:auto temp = it;
|
||
temp += n;return temp;
|
||
|
||
[ð](#lib:operator+,concat_view::iterator_)
|
||
|
||
`friend constexpr iterator operator+(difference_type n, const iterator& it)
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[31](#range.concat.iterator-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9486)
|
||
|
||
*Effects*: Equivalent to:return it + n;
|
||
|
||
[ð](#lib:operator-,concat_view::iterator)
|
||
|
||
`friend constexpr iterator operator-(const iterator& it, difference_type n)
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[32](#range.concat.iterator-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9501)
|
||
|
||
*Effects*: Equivalent to:auto temp = it;
|
||
temp -= n;return temp;
|
||
|
||
[ð](#lib:operator-,concat_view::iterator_)
|
||
|
||
`friend constexpr difference_type operator-(const iterator& x, const iterator& y)
|
||
requires [concat-is-random-access](#concept:concat-is-random-access "25.7.18.2 Class template concat_view [range.concat.view]")<Const, Views...>;
|
||
`
|
||
|
||
[33](#range.concat.iterator-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9518)
|
||
|
||
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#range.concat.iterator-33.sentence-1)
|
||
|
||
[34](#range.concat.iterator-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9523)
|
||
|
||
*Effects*: Letix denote x.*it_*.index() andiy denote y.*it_*.index()[.](#range.concat.iterator-34.sentence-1)
|
||
|
||
- [(34.1)](#range.concat.iterator-34.1)
|
||
|
||
If ix > iy, letdy beranges::distance(std::get<iy>(y.*it_*), ranges::end(std::get<iy>(y.*parent_*->*views_*))),dx beranges::distance(ranges::begin(std::get<ix>(x.*parent_*->*views_*)), std::get<ix>(x.*it_*)). Let s denote the sum of the sizes of all the rangesstd::get<i>(x.*parent_*->*views_*) for every integer i in the range
|
||
[iy + 1, ix)
|
||
if there is any, and0 otherwise,
|
||
of type difference_type,
|
||
equivalent to:return dy + s + dx;
|
||
|
||
- [(34.2)](#range.concat.iterator-34.2)
|
||
|
||
otherwise, if ix < iy is true,
|
||
equivalent to:return -(y - x);
|
||
|
||
- [(34.3)](#range.concat.iterator-34.3)
|
||
|
||
otherwise, equivalent to:return std::get<ix>(x.*it_*) - std::get<iy>(y.*it_*);
|
||
|
||
[ð](#lib:operator-,concat_view::iterator__)
|
||
|
||
`friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
|
||
requires see below;
|
||
`
|
||
|
||
[35](#range.concat.iterator-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9571)
|
||
|
||
*Preconditions*: x.*it_*.valueless_by_exception() is false[.](#range.concat.iterator-35.sentence-1)
|
||
|
||
[36](#range.concat.iterator-36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9575)
|
||
|
||
*Effects*: Letix denote x.*it_*.index(),dx beranges::distance(std::get<ix>(x.*it_*), ranges::end(std::get<ix>(x.*parent_*->*views_*)))[.](#range.concat.iterator-36.sentence-1)
|
||
|
||
Let s denote the sum of the sizes of all the rangesstd::get<i>(x.*parent_*->*views_*) for every integer i in the range
|
||
[ix + 1, sizeof...(Views))
|
||
if there is any, and0 otherwise,
|
||
of type difference_type,
|
||
equivalent to:return -(dx + s);
|
||
|
||
[37](#range.concat.iterator-37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9594)
|
||
|
||
*Remarks*: Let Fs be the pack that consists of all elements of Views except the first element,
|
||
the expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to:([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
|
||
iterator_t<*maybe-const*<Const, Views>>> && ...) &&([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<*maybe-const*<Const, Fs>> && ...)
|
||
|
||
[ð](#lib:operator-,concat_view::iterator___)
|
||
|
||
`friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
|
||
requires see below;
|
||
`
|
||
|
||
[38](#range.concat.iterator-38)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9614)
|
||
|
||
*Effects*: Equivalent to:return -(x - default_sentinel);
|
||
|
||
[39](#range.concat.iterator-39)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9621)
|
||
|
||
*Remarks*: Let Fs be the pack that consists of all elements of Views except the first element,
|
||
the expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to:([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
|
||
iterator_t<*maybe-const*<Const, Views>>> && ...) &&([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<*maybe-const*<Const, Fs>> && ...)
|
||
|
||
[ð](#lib:iter_move,concat_view::iterator)
|
||
|
||
`friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
|
||
`
|
||
|
||
[40](#range.concat.iterator-40)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9639)
|
||
|
||
*Preconditions*: it.*it_*.valueless_by_exception() is false[.](#range.concat.iterator-40.sentence-1)
|
||
|
||
[41](#range.concat.iterator-41)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9643)
|
||
|
||
*Effects*: Equivalent to:return std::visit([](const auto& i)-> *concat-rvalue-reference-t*<*maybe-const*<Const, Views>...> {return ranges::iter_move(i); },
|
||
it.*it_*);
|
||
|
||
[42](#range.concat.iterator-42)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9654)
|
||
|
||
*Remarks*: The exception specification is equivalent to:((is_nothrow_invocable_v<decltype(ranges::iter_move), const iterator_t<*maybe-const*<Const, Views>>&> && is_nothrow_convertible_v<range_rvalue_reference_t<*maybe-const*<Const, Views>>, *concat-rvalue-reference-t*<*maybe-const*<Const, Views>...>>) &&...)
|
||
|
||
[ð](#lib:iter_swap,concat_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
|
||
requires see below;
|
||
`
|
||
|
||
[43](#range.concat.iterator-43)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9673)
|
||
|
||
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#range.concat.iterator-43.sentence-1)
|
||
|
||
[44](#range.concat.iterator-44)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9678)
|
||
|
||
*Effects*: Equivalent to:std::visit([&](const auto& it1, const auto& it2) {if constexpr (is_same_v<decltype(it1), decltype(it2)>) { ranges::iter_swap(it1, it2); } else { ranges::swap(*x, *y); }},
|
||
x.*it_*, y.*it_*);
|
||
|
||
[45](#range.concat.iterator-45)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9692)
|
||
|
||
*Remarks*: The exception specification is equivalent to(noexcept(ranges::swap(*x, *y)) && ... && noexcept(ranges::iter_swap(its, its))) where its is a pack of lvalues of typeconst iterator_t<*maybe-const*<Const, Views>> respectively[.](#range.concat.iterator-45.sentence-1)
|
||
|
||
The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to[swappable_with](concept.swappable#concept:swappable_with "18.4.9 Concept swappable [concept.swappable]")<iter_reference_t<*iterator*>, iter_reference_t<*iterator*>> &&(... && [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, Views>>>)
|
||
|
||
### [25.7.19](#range.counted) Counted view [[range.counted]](range.counted)
|
||
|
||
[1](#range.counted-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9712)
|
||
|
||
A counted view presents a view of the elements
|
||
of the counted range ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")) i+[0, n) for an iterator i and non-negative integer n[.](#range.counted-1.sentence-1)
|
||
|
||
[2](#range.counted-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9718)
|
||
|
||
The name views::counted denotes
|
||
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))[.](#range.counted-2.sentence-1)
|
||
|
||
Let E and F be expressions,
|
||
let T be decay_t<decltype((E))>, and
|
||
let D be iter_difference_t<T>[.](#range.counted-2.sentence-2)
|
||
|
||
If decltype((F)) does not model[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<D>,views::counted(E, F) is ill-formed[.](#range.counted-2.sentence-3)
|
||
|
||
[*Note [1](#range.counted-note-1)*:
|
||
|
||
This case can result in substitution failure
|
||
when views::counted(E, F) appears in the immediate context of a template instantiation[.](#range.counted-2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
Otherwise, views::counted(E, F) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.counted-2.1)
|
||
|
||
If T models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_iterator [iterator.concept.contiguous]"),
|
||
then span(to_address(E), static_cast<size_t>(static_cast<D>(F)))[.](#range.counted-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.counted-2.2)
|
||
|
||
Otherwise, if T models [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]"),
|
||
then subrange(E, E + static_cast<D>(F)),
|
||
except that E is evaluated only once[.](#range.counted-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.counted-2.3)
|
||
|
||
Otherwise,subrange(counted_iterator(E, F), default_sentinel)[.](#range.counted-2.3.sentence-1)
|
||
|
||
### [25.7.20](#range.common) Common view [[range.common]](range.common)
|
||
|
||
#### [25.7.20.1](#range.common.overview) Overview [[range.common.overview]](range.common.overview)
|
||
|
||
[1](#range.common.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9754)
|
||
|
||
common_view takes a view which has different types for
|
||
its iterator and sentinel and turns it into a view of the same
|
||
elements with an iterator and sentinel of the same type[.](#range.common.overview-1.sentence-1)
|
||
|
||
[2](#range.common.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9759)
|
||
|
||
[*Note [1](#range.common.overview-note-1)*:
|
||
|
||
common_view is useful for calling legacy algorithms that expect
|
||
a range's iterator and sentinel types to be the same[.](#range.common.overview-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[3](#range.common.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9765)
|
||
|
||
The name views::common denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.common.overview-3.sentence-1)
|
||
|
||
Given a subexpression E,
|
||
the expression views::common(E) is expression-equivalent to:
|
||
|
||
- [(3.1)](#range.common.overview-3.1)
|
||
|
||
views::all(E),
|
||
if decltype((E)) models [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]") and views::all(E) is a well-formed expression[.](#range.common.overview-3.1.sentence-1)
|
||
|
||
- [(3.2)](#range.common.overview-3.2)
|
||
|
||
Otherwise, common_view{E}[.](#range.common.overview-3.2.sentence-1)
|
||
|
||
[4](#range.common.overview-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9779)
|
||
|
||
[*Example [1](#range.common.overview-example-1)*: // Legacy algorithm:template<class ForwardIterator> size_t count(ForwardIterator first, ForwardIterator last);
|
||
|
||
template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") R>void my_algo(R&& r) {auto&& common = views::common(r); auto cnt = count(common.begin(), common.end()); // ...} â *end example*]
|
||
|
||
#### [25.7.20.2](#range.common.view) Class template common_view [[range.common.view]](range.common.view)
|
||
|
||
[ð](#lib:common_view)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires (<V> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<iterator_t<V>>)class common_view : public view_interface<common_view<V>> {private: V *base_* = V(); // *exposition only*public: common_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit common_view(V r); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>) {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>)return ranges::begin(*base_*); elsereturn common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::begin(*base_*)); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>)return ranges::begin(*base_*); elsereturn common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::begin(*base_*)); }constexpr auto end() requires (<V>) {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>)return ranges::begin(*base_*) + ranges::distance(*base_*); elsereturn common_iterator<iterator_t<V>, sentinel_t<V>>(ranges::end(*base_*)); }constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>)return ranges::begin(*base_*) + ranges::distance(*base_*); elsereturn common_iterator<iterator_t<const V>, sentinel_t<const V>>(ranges::end(*base_*)); }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> {return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> {return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V> {return ranges::reserve_hint(*base_*); }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]")<const V> {return ranges::reserve_hint(*base_*); }}; template<class R> common_view(R&&) -> common_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:common_view,constructor)
|
||
|
||
`constexpr explicit common_view(V base);
|
||
`
|
||
|
||
[1](#range.common.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9872)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.common.view-1.sentence-1)
|
||
|
||
### [25.7.21](#range.reverse) Reverse view [[range.reverse]](range.reverse)
|
||
|
||
#### [25.7.21.1](#range.reverse.overview) Overview [[range.reverse.overview]](range.reverse.overview)
|
||
|
||
[1](#range.reverse.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9881)
|
||
|
||
reverse_view takes a bidirectional view and produces
|
||
another view that iterates the same elements in reverse order[.](#range.reverse.overview-1.sentence-1)
|
||
|
||
[2](#range.reverse.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9885)
|
||
|
||
The name views::reverse denotes a
|
||
range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.reverse.overview-2.sentence-1)
|
||
|
||
Given a subexpression E, the expressionviews::reverse(E) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.reverse.overview-2.1)
|
||
|
||
If the type of E is
|
||
a (possibly cv-qualified) specialization of reverse_view,
|
||
then E.base()[.](#range.reverse.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.reverse.overview-2.2)
|
||
|
||
Otherwise, if the type of E is cv subrange<reverse_iterator<I>, reverse_iterator<I>, K> for some iterator type I and
|
||
value K of type subrange_kind,
|
||
* [(2.2.1)](#range.reverse.overview-2.2.1)
|
||
|
||
if K is subrange_kind::sized, thensubrange<I, I, K>(E.end().base(), E.begin().base(), E.size());
|
||
|
||
* [(2.2.2)](#range.reverse.overview-2.2.2)
|
||
|
||
otherwise, subrange<I, I, K>(E.end().base(), E.begin().base())[.](#range.reverse.overview-2.2.sentence-1)
|
||
|
||
However, in either case E is evaluated only once[.](#range.reverse.overview-2.2.sentence-2)
|
||
|
||
- [(2.3)](#range.reverse.overview-2.3)
|
||
|
||
Otherwise, reverse_view{E}[.](#range.reverse.overview-2.3.sentence-1)
|
||
|
||
[3](#range.reverse.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9912)
|
||
|
||
[*Example [1](#range.reverse.overview-example-1)*: vector<int> is {0,1,2,3,4};for (int i : is | views::reverse) cout << i << ' '; // prints 4 3 2 1 0 â *end example*]
|
||
|
||
#### [25.7.21.2](#range.reverse.view) Class template reverse_view [[range.reverse.view]](range.reverse.view)
|
||
|
||
[ð](#lib:reverse_view)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>class reverse_view : public view_interface<reverse_view<V>> {private: V *base_* = V(); // *exposition only*public: reverse_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit reverse_view(V r); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr reverse_iterator<iterator_t<V>> begin(); constexpr reverse_iterator<iterator_t<V>> begin() requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>; constexpr auto begin() const requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>; constexpr reverse_iterator<iterator_t<V>> end(); constexpr auto end() const requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>; constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> {return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> {return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V> {return ranges::reserve_hint(*base_*); }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]")<const V> {return ranges::reserve_hint(*base_*); }}; template<class R> reverse_view(R&&) -> reverse_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:reverse_view,constructor)
|
||
|
||
`constexpr explicit reverse_view(V base);
|
||
`
|
||
|
||
[1](#range.reverse.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9976)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.reverse.view-1.sentence-1)
|
||
|
||
[ð](#lib:begin,reverse_view)
|
||
|
||
`constexpr reverse_iterator<iterator_t<V>> begin();
|
||
`
|
||
|
||
[2](#range.reverse.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9987)
|
||
|
||
*Returns*: make_reverse_iterator(ranges::next(ranges::begin(*base_*), ranges::end(*base_*)))
|
||
|
||
[3](#range.reverse.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9993)
|
||
|
||
*Remarks*: In order to provide the amortized constant time complexity required by
|
||
the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept, this function caches the result within thereverse_view for use on subsequent calls[.](#range.reverse.view-3.sentence-1)
|
||
|
||
[ð](#lib:begin,reverse_view_)
|
||
|
||
`constexpr reverse_iterator<iterator_t<V>> begin() requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
constexpr auto begin() const requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>;
|
||
`
|
||
|
||
[4](#range.reverse.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10007)
|
||
|
||
*Effects*: Equivalent to: return make_reverse_iterator(ranges::end(*base_*));
|
||
|
||
[ð](#lib:end,reverse_view)
|
||
|
||
`constexpr reverse_iterator<iterator_t<V>> end();
|
||
constexpr auto end() const requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>;
|
||
`
|
||
|
||
[5](#range.reverse.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10019)
|
||
|
||
*Effects*: Equivalent to: return make_reverse_iterator(ranges::begin(*base_*));
|
||
|
||
### [25.7.22](#range.as.const) As const view [[range.as.const]](range.as.const)
|
||
|
||
#### [25.7.22.1](#range.as.const.overview) Overview [[range.as.const.overview]](range.as.const.overview)
|
||
|
||
[1](#range.as.const.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10028)
|
||
|
||
as_const_view presents a view of an underlying sequence as constant[.](#range.as.const.overview-1.sentence-1)
|
||
|
||
That is, the elements of an as_const_view cannot be modified[.](#range.as.const.overview-1.sentence-2)
|
||
|
||
[2](#range.as.const.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10032)
|
||
|
||
The name views::as_const denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.as.const.overview-2.sentence-1)
|
||
|
||
Let E be an expression,
|
||
let T be decltype((E)), and
|
||
let U be remove_cvref_t<T>[.](#range.as.const.overview-2.sentence-2)
|
||
|
||
The expression views::as_const(E) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.as.const.overview-2.1)
|
||
|
||
If views::all_t<T> models [constant_range](range.refinements#concept:constant_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then views::all(E)[.](#range.as.const.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.as.const.overview-2.2)
|
||
|
||
Otherwise,
|
||
if U denotes empty_view<X> for some type X, then auto(views::empty<const X>)[.](#range.as.const.overview-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.as.const.overview-2.3)
|
||
|
||
Otherwise,
|
||
if U denotes span<X, Extent> for some type X and some extent Extent,
|
||
then span<const X, Extent>(E)[.](#range.as.const.overview-2.3.sentence-1)
|
||
|
||
- [(2.4)](#range.as.const.overview-2.4)
|
||
|
||
Otherwise,
|
||
if U denotes ref_view<X> for some type X andconst X models [constant_range](range.refinements#concept:constant_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then ref_view(static_cast<const X&>(E.base()))[.](#range.as.const.overview-2.4.sentence-1)
|
||
|
||
- [(2.5)](#range.as.const.overview-2.5)
|
||
|
||
Otherwise,
|
||
if E is an lvalue,const U models [constant_range](range.refinements#concept:constant_range "25.4.6 Other range refinements [range.refinements]"), andU does not model [view](range.view#concept:view "25.4.5 Views [range.view]"),
|
||
then ref_view(static_cast<const U&>(E))[.](#range.as.const.overview-2.5.sentence-1)
|
||
|
||
- [(2.6)](#range.as.const.overview-2.6)
|
||
|
||
Otherwise, as_const_view(E)[.](#range.as.const.overview-2.6.sentence-1)
|
||
|
||
[3](#range.as.const.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10067)
|
||
|
||
[*Example [1](#range.as.const.overview-example-1)*: template<[constant_range](range.refinements#concept:constant_range "25.4.6 Other range refinements [range.refinements]") R>void cant_touch_this(R&&);
|
||
|
||
vector<char> hammer = {'m', 'c'};
|
||
span<char> beat = hammer;
|
||
cant_touch_this(views::as_const(beat)); // will not modify the elements of hammer â *end example*]
|
||
|
||
#### [25.7.22.2](#range.as.const.view) Class template as_const_view [[range.as.const.view]](range.as.const.view)
|
||
|
||
[ð](#lib:as_const_view::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]")<V>class as_const_view : public view_interface<as_const_view<V>> { V *base_* = V(); // *exposition only*public: as_const_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit as_const_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>) { return ranges::cbegin(*base_*); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> { return ranges::cbegin(*base_*); }constexpr auto end() requires (<V>) { return ranges::cend(*base_*); }constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> { return ranges::cend(*base_*); }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> { return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> { return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>{ return ranges::reserve_hint(*base_*); }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]")<const V>{ return ranges::reserve_hint(*base_*); }}; template<class R> as_const_view(R&&) -> as_const_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:as_const_view::iterator,constructor)
|
||
|
||
`constexpr explicit as_const_view(V base);
|
||
`
|
||
|
||
[1](#range.as.const.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10122)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.as.const.view-1.sentence-1)
|
||
|
||
### [25.7.23](#range.elements) Elements view [[range.elements]](range.elements)
|
||
|
||
#### [25.7.23.1](#range.elements.overview) Overview [[range.elements.overview]](range.elements.overview)
|
||
|
||
[1](#range.elements.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10131)
|
||
|
||
elements_view takes
|
||
a view of tuple-like values and a size_t, and
|
||
produces a view with a value-type of the Nth element
|
||
of the adapted view's value-type[.](#range.elements.overview-1.sentence-1)
|
||
|
||
[2](#range.elements.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10137)
|
||
|
||
The name views::elements<N> denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.elements.overview-2.sentence-1)
|
||
|
||
Given a subexpression E and constant expression N,
|
||
the expression views::elements<N>(E) is expression-equivalent toelements_view<views::all_t<decltype((E))>, N>{E}[.](#range.elements.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.elements.overview-example-1)*: auto historical_figures = map{ pair{"Lovelace"sv, 1815}, {"Turing"sv, 1912}, {"Babbage"sv, 1791}, {"Hamilton"sv, 1936}};
|
||
|
||
auto names = historical_figures | views::elements<0>;for (auto&& name : names) { cout << name << ' '; // prints Babbage Hamilton Lovelace Turing }auto birth_years = historical_figures | views::elements<1>;for (auto&& born : birth_years) { cout << born << ' '; // prints 1791 1936 1815 1912 } â *end example*]
|
||
|
||
[3](#range.elements.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10166)
|
||
|
||
keys_view is an alias for elements_view<R, 0>, and
|
||
is useful for extracting keys from associative containers[.](#range.elements.overview-3.sentence-1)
|
||
|
||
[*Example [2](#range.elements.overview-example-2)*: auto names = historical_figures | views::keys;for (auto&& name : names) { cout << name << ' '; // prints Babbage Hamilton Lovelace Turing } â *end example*]
|
||
|
||
[4](#range.elements.overview-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10179)
|
||
|
||
values_view is an alias for elements_view<R, 1>, and
|
||
is useful for extracting values from associative containers[.](#range.elements.overview-4.sentence-1)
|
||
|
||
[*Example [3](#range.elements.overview-example-3)*: auto is_even = [](const auto x) { return x % 2 == 0; };
|
||
cout << ranges::count_if(historical_figures | views::values, is_even); // prints 2 â *end example*]
|
||
|
||
#### [25.7.23.2](#range.elements.view) Class template elements_view [[range.elements.view]](range.elements.view)
|
||
|
||
[ð](#lib:elements_view)
|
||
|
||
namespace std::ranges {template<class T, size_t N>concept [*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]") = // *exposition only*[*tuple-like*](tuple.like#concept:tuple-like "22.4.3 Concept tuple-like [tuple.like]")<T> && N < tuple_size_v<T>; template<class T, size_t N>concept [*returnable-element*](#concept:returnable-element "25.7.23.2 Class template elements_view [range.elements.view]") = // *exposition only* is_reference_v<T> || [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<tuple_element_t<N, T>>; template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]")<range_value_t<V>, N> &&[*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]")<remove_reference_t<range_reference_t<V>>, N> &&[*returnable-element*](#concept:returnable-element "25.7.23.2 Class template elements_view [range.elements.view]")<range_reference_t<V>, N>class elements_view : public view_interface<elements_view<V, N>> {public: elements_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit elements_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>){ return *iterator*<false>(ranges::begin(*base_*)); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>{ return *iterator*<true>(ranges::begin(*base_*)); }constexpr auto end() requires (<V> && <V>){ return *sentinel*<false>{ranges::end(*base_*)}; }constexpr auto end() requires (<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>){ return *iterator*<false>{ranges::end(*base_*)}; }constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>{ return *sentinel*<true>{ranges::end(*base_*)}; }constexpr auto end() const requires [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>{ return *iterator*<true>{ranges::end(*base_*)}; }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>{ return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>{ return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>{ return ranges::reserve_hint(*base_*); }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]")<const V>{ return ranges::reserve_hint(*base_*); }private:// [[range.elements.iterator]](#range.elements.iterator "25.7.23.3 Class template elements_view::iterator"), class template elements_view::*iterator*template<bool> class *iterator*; // *exposition only*// [[range.elements.sentinel]](#range.elements.sentinel "25.7.23.4 Class template elements_view::sentinel"), class template elements_view::*sentinel*template<bool> class *sentinel*; // *exposition only* V *base_* = V(); // *exposition only*};}
|
||
|
||
[ð](#lib:elements_view,constructor)
|
||
|
||
`constexpr explicit elements_view(V base);
|
||
`
|
||
|
||
[1](#range.elements.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10267)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.elements.view-1.sentence-1)
|
||
|
||
#### [25.7.23.3](#range.elements.iterator) Class template elements_view::*iterator* [[range.elements.iterator]](range.elements.iterator)
|
||
|
||
[ð](#lib:elements_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]")<range_value_t<V>, N> &&[*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]")<remove_reference_t<range_reference_t<V>>, N> &&[*returnable-element*](#concept:returnable-element "25.7.23.2 Class template elements_view [range.elements.view]")<range_reference_t<V>, N>template<bool Const>class elements_view<V, N>::*iterator* {using *Base* = *maybe-const*<Const, V>; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only*static constexpr decltype(auto) *get-element*(const iterator_t<*Base*>& i); // *exposition only*public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = remove_cvref_t<tuple_element_t<N, range_value_t<*Base*>>>; using difference_type = range_difference_t<*Base*>; *iterator*() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iterator_t<*Base*>> = default; constexpr explicit *iterator*(iterator_t<*Base*> current); constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr const iterator_t<*Base*>& base() const & noexcept; constexpr iterator_t<*Base*> base() &&; constexpr decltype(auto) operator*() const{ return *get-element*(*current_*); }constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; 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 decltype(auto) operator[](difference_type n) constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>{ return *get-element*(*current_* + n); }friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<*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 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]")<iterator_t<*Base*>>; friend constexpr *iterator* operator+(const *iterator*& x, difference_type y)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 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 *iterator* operator-(const *iterator*& x, difference_type y)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*>, iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.elements.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10348)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.elements.iterator-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[.](#range.elements.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.elements.iterator-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[.](#range.elements.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.elements.iterator-1.3)
|
||
|
||
Otherwise, if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.elements.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.elements.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.elements.iterator-1.4.sentence-1)
|
||
|
||
[2](#range.elements.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10365)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.elements.iterator-2.sentence-1)
|
||
|
||
In that case, iterator_category is defined as follows:
|
||
Let C denote the typeiterator_traits<iterator_t<*Base*>>::iterator_category[.](#range.elements.iterator-2.sentence-2)
|
||
|
||
- [(2.1)](#range.elements.iterator-2.1)
|
||
|
||
If std::get<N>(**current_*) is an rvalue,iterator_category denotes input_iterator_tag[.](#range.elements.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.elements.iterator-2.2)
|
||
|
||
Otherwise, if C models [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<random_access_iterator_tag>,iterator_category denotes random_access_iterator_tag[.](#range.elements.iterator-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.elements.iterator-2.3)
|
||
|
||
Otherwise, iterator_category denotes C[.](#range.elements.iterator-2.3.sentence-1)
|
||
|
||
[ð](#lib:get-element,elements_view::iterator)
|
||
|
||
`static constexpr decltype(auto) get-element(const iterator_t<Base>& i);
|
||
`
|
||
|
||
[3](#range.elements.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10388)
|
||
|
||
*Effects*: Equivalent to:if constexpr (is_reference_v<range_reference_t<*Base*>>) {return std::get<N>(*i);} else {using E = remove_cv_t<tuple_element_t<N, range_reference_t<*Base*>>>; return static_cast<E>(std::get<N>(*i));}
|
||
|
||
[ð](#lib:elements_view::iterator,constructor)
|
||
|
||
`constexpr explicit iterator(iterator_t<Base> current);
|
||
`
|
||
|
||
[4](#range.elements.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10407)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current)[.](#range.elements.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:elements_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[5](#range.elements.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10419)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*)[.](#range.elements.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:base,elements_view::iterator)
|
||
|
||
`constexpr const iterator_t<Base>& base() const & noexcept;
|
||
`
|
||
|
||
[6](#range.elements.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10430)
|
||
|
||
*Effects*: Equivalent to: return *current_*;
|
||
|
||
[ð](#lib:base,elements_view::iterator_)
|
||
|
||
`constexpr iterator_t<Base> base() &&;
|
||
`
|
||
|
||
[7](#range.elements.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10441)
|
||
|
||
*Effects*: Equivalent to: return std::move(*current_*);
|
||
|
||
[ð](#lib:operator++,elements_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[8](#range.elements.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10452)
|
||
|
||
*Effects*: Equivalent to:++*current_*;return *this;
|
||
|
||
[ð](#lib:operator++,elements_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[9](#range.elements.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10467)
|
||
|
||
*Effects*: Equivalent to: ++*current_*[.](#range.elements.iterator-9.sentence-1)
|
||
|
||
[ð](#lib:operator++,elements_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[10](#range.elements.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10478)
|
||
|
||
*Effects*: Equivalent to:auto temp = *this;++*current_*;return temp;
|
||
|
||
[ð](#lib:operator--,elements_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[11](#range.elements.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10494)
|
||
|
||
*Effects*: Equivalent to:--*current_*;return *this;
|
||
|
||
[ð](#lib:operator--,elements_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[12](#range.elements.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10509)
|
||
|
||
*Effects*: Equivalent to:auto temp = *this;--*current_*;return temp;
|
||
|
||
[ð](#lib:operator+=,elements_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[13](#range.elements.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10526)
|
||
|
||
*Effects*: Equivalent to:*current_* += n;return *this;
|
||
|
||
[ð](#lib:operator-=,elements_view::iterator)
|
||
|
||
`constexpr iterator& operator-=(difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[14](#range.elements.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10542)
|
||
|
||
*Effects*: Equivalent to:*current_* -= n;return *this;
|
||
|
||
[ð](#lib:operator==,elements_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<Base>;
|
||
`
|
||
|
||
[15](#range.elements.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10558)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*current_*;
|
||
|
||
[ð](#lib:operator%3c,elements_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]")<Base>;
|
||
`
|
||
|
||
[16](#range.elements.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10570)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* < y.*current_*;
|
||
|
||
[ð](#lib:operator%3e,elements_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]")<Base>;
|
||
`
|
||
|
||
[17](#range.elements.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10582)
|
||
|
||
*Effects*: Equivalent to: return y < x;
|
||
|
||
[ð](#lib:operator%3c=,elements_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]")<Base>;
|
||
`
|
||
|
||
[18](#range.elements.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10594)
|
||
|
||
*Effects*: Equivalent to: return !(y < x);
|
||
|
||
[ð](#lib:operator%3e=,elements_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]")<Base>;
|
||
`
|
||
|
||
[19](#range.elements.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10606)
|
||
|
||
*Effects*: Equivalent to: return !(x < y);
|
||
|
||
[ð](#lib:operator%3c=%3e,elements_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]")<Base> && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[20](#range.elements.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10618)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* <=> y.*current_*;
|
||
|
||
[ð](#lib:operator+,elements_view::iterator)
|
||
|
||
`friend constexpr iterator operator+(const iterator& x, difference_type y)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[21](#range.elements.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10630)
|
||
|
||
*Effects*: Equivalent to: return *iterator*{x} += y;
|
||
|
||
[ð](#lib:operator+,elements_view::iterator_)
|
||
|
||
`friend constexpr iterator operator+(difference_type x, const iterator& y)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[22](#range.elements.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10642)
|
||
|
||
*Effects*: Equivalent to: return y + x;
|
||
|
||
[ð](#lib:operator-,elements_view::iterator)
|
||
|
||
`friend constexpr iterator operator-(const iterator& x, difference_type y)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[23](#range.elements.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10654)
|
||
|
||
*Effects*: Equivalent to: return *iterator*{x} -= y;
|
||
|
||
[ð](#lib:operator-,elements_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<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[24](#range.elements.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10666)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* - y.*current_*;
|
||
|
||
#### [25.7.23.4](#range.elements.sentinel) Class template elements_view::*sentinel* [[range.elements.sentinel]](range.elements.sentinel)
|
||
|
||
[ð](#lib:elements_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && [*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]")<range_value_t<V>, N> &&[*has-tuple-element*](#concept:has-tuple-element "25.7.23.2 Class template elements_view [range.elements.view]")<remove_reference_t<range_reference_t<V>>, N> &&[*returnable-element*](#concept:returnable-element "25.7.23.2 Class template elements_view [range.elements.view]")<range_reference_t<V>, N>template<bool Const>class elements_view<V, N>::*sentinel* {private:using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(sentinel_t<*Base*> end); constexpr *sentinel*(*sentinel*<!Const> other)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; constexpr sentinel_t<*Base*> base() const; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *sentinel*& x, const *iterator*<OtherConst>& y); };}
|
||
|
||
[ð](#lib:elements_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<Base> end);
|
||
`
|
||
|
||
[1](#range.elements.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10717)
|
||
|
||
*Effects*: Initializes *end_* with end[.](#range.elements.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:elements_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> other)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.elements.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10729)
|
||
|
||
*Effects*: Initializes *end_* with std::move(other.*end_*)[.](#range.elements.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:base,elements_view::sentinel)
|
||
|
||
`constexpr sentinel_t<Base> base() const;
|
||
`
|
||
|
||
[3](#range.elements.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10740)
|
||
|
||
*Effects*: Equivalent to: return *end_*;
|
||
|
||
[ð](#lib:operator==,elements_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[4](#range.elements.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10753)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*end_*;
|
||
|
||
[ð](#lib:operator-,elements_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[5](#range.elements.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10767)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* - y.*end_*;
|
||
|
||
[ð](#lib:operator-,elements_view::sentinel_)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
||
`
|
||
|
||
[6](#range.elements.sentinel-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10781)
|
||
|
||
*Effects*: Equivalent to: return x.*end_* - y.*current_*;
|
||
|
||
### [25.7.24](#range.enumerate) Enumerate view [[range.enumerate]](range.enumerate)
|
||
|
||
#### [25.7.24.1](#range.enumerate.overview) Overview [[range.enumerate.overview]](range.enumerate.overview)
|
||
|
||
[1](#range.enumerate.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10790)
|
||
|
||
enumerate_view is a view whose
|
||
elements represent both the position and value from
|
||
a sequence of elements[.](#range.enumerate.overview-1.sentence-1)
|
||
|
||
[2](#range.enumerate.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10796)
|
||
|
||
The name views::enumerate denotes a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.enumerate.overview-2.sentence-1)
|
||
|
||
Given a subexpression E,
|
||
the expression views::enumerate(E) is expression-equivalent toenumerate_view<views::all_t<decltype((E))>>(E)[.](#range.enumerate.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.enumerate.overview-example-1)*: vector<int> vec{ 1, 2, 3 };for (auto [index, value] : views::enumerate(vec)) cout << index << ":" << value << ' '; // prints 0:1 1:2 2:3 â *end example*]
|
||
|
||
#### [25.7.24.2](#range.enumerate.view) Class template enumerate_view [[range.enumerate.view]](range.enumerate.view)
|
||
|
||
[ð](#lib:enumerate_view_)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [*range-with-movable-references*](range.utility.helpers#concept:range-with-movable-references "25.5.2 Helper concepts [range.utility.helpers]")<V>class enumerate_view : public view_interface<enumerate_view<V>> { V *base_* = V(); // *exposition only*// [[range.enumerate.iterator]](#range.enumerate.iterator "25.7.24.3 Class template enumerate_view::iterator"), class template enumerate_view::*iterator*template<bool Const>class *iterator*; // *exposition only*// [[range.enumerate.sentinel]](#range.enumerate.sentinel "25.7.24.4 Class template enumerate_view::sentinel"), class template enumerate_view::*sentinel*template<bool Const>class *sentinel*; // *exposition only*public:constexpr enumerate_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit enumerate_view(V base); constexpr auto begin() requires (<V>){ return *iterator*<false>(ranges::begin(*base_*), 0); }constexpr auto begin() const requires [*range-with-movable-references*](range.utility.helpers#concept:range-with-movable-references "25.5.2 Helper concepts [range.utility.helpers]")<const V>{ return *iterator*<true>(ranges::begin(*base_*), 0); }constexpr auto end() requires (<V>) {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>)return *iterator*<false>(ranges::end(*base_*), ranges::distance(*base_*)); elsereturn *sentinel*<false>(ranges::end(*base_*)); }constexpr auto end() const requires [*range-with-movable-references*](range.utility.helpers#concept:range-with-movable-references "25.5.2 Helper concepts [range.utility.helpers]")<const V> {if constexpr ([forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>)return *iterator*<true>(ranges::end(*base_*), ranges::distance(*base_*)); elsereturn *sentinel*<true>(ranges::end(*base_*)); }constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>{ return ranges::size(*base_*); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>{ return ranges::size(*base_*); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>{ return ranges::reserve_hint(*base_*); }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]")<const V>{ return ranges::reserve_hint(*base_*); }constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }}; template<class R> enumerate_view(R&&) -> enumerate_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:enumerate_view,constructor)
|
||
|
||
`constexpr explicit enumerate_view(V base);
|
||
`
|
||
|
||
[1](#range.enumerate.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10878)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.enumerate.view-1.sentence-1)
|
||
|
||
#### [25.7.24.3](#range.enumerate.iterator) Class template enumerate_view::*iterator* [[range.enumerate.iterator]](range.enumerate.iterator)
|
||
|
||
[ð](#lib:enumerate_view::iterator)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [*range-with-movable-references*](range.utility.helpers#concept:range-with-movable-references "25.5.2 Helper concepts [range.utility.helpers]")<V>template<bool Const>class enumerate_view<V>::*iterator* {using *Base* = *maybe-const*<Const, V>; // *exposition only*public:using iterator_category = input_iterator_tag; using iterator_concept = *see below*; using difference_type = range_difference_t<*Base*>; using value_type = tuple<difference_type, range_value_t<*Base*>>; private:using *reference-type* = // *exposition only* tuple<difference_type, range_reference_t<*Base*>>;
|
||
iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only* difference_type *pos_* = 0; // *exposition only*constexpr explicit*iterator*(iterator_t<*Base*> current, difference_type pos); // *exposition only*public:*iterator*() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iterator_t<*Base*>> = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr const iterator_t<*Base*>& base() const & noexcept; constexpr iterator_t<*Base*> base() &&; constexpr difference_type index() const noexcept; constexpr auto operator*() const {return *reference-type*(*pos_*, **current_*); }constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; 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 auto operator[](difference_type n) constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>{ return *reference-type*(*pos_* + n, *current_*[n]); }friend constexpr bool operator==(const *iterator*& x, const *iterator*& y) noexcept; friend constexpr strong_ordering operator<=>(const *iterator*& x, const *iterator*& y) noexcept; friend constexpr *iterator* operator+(const *iterator*& x, difference_type y)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 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 *iterator* operator-(const *iterator*& x, difference_type y)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) noexcept; friend constexpr auto iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(i.*current_*)) && is_nothrow_move_constructible_v<range_rvalue_reference_t<*Base*>>) {return tuple<difference_type,
|
||
range_rvalue_reference_t<*Base*>>(i.*pos_*, ranges::iter_move(i.*current_*)); }};}
|
||
|
||
[1](#range.enumerate.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10960)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.enumerate.iterator-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[.](#range.enumerate.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.enumerate.iterator-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[.](#range.enumerate.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.enumerate.iterator-1.3)
|
||
|
||
Otherwise, if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.enumerate.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.enumerate.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.enumerate.iterator-1.4.sentence-1)
|
||
|
||
[ð](#lib:enumerate_view::iterator,constructor)
|
||
|
||
`constexpr explicit iterator(iterator_t<Base> current, difference_type pos);
|
||
`
|
||
|
||
[2](#range.enumerate.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10984)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current) and*pos_* with pos[.](#range.enumerate.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:enumerate_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[3](#range.enumerate.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L10997)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*) and*pos_* with i.*pos_*[.](#range.enumerate.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:base,enumerate_view::iterator)
|
||
|
||
`constexpr const iterator_t<Base>& base() const & noexcept;
|
||
`
|
||
|
||
[4](#range.enumerate.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11009)
|
||
|
||
*Effects*: Equivalent to: return *current_*;
|
||
|
||
[ð](#lib:base,enumerate_view::iterator_)
|
||
|
||
`constexpr iterator_t<Base> base() &&;
|
||
`
|
||
|
||
[5](#range.enumerate.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11020)
|
||
|
||
*Effects*: Equivalent to: return std::move(*current_*);
|
||
|
||
[ð](#lib:index,enumerate_view::iterator)
|
||
|
||
`constexpr difference_type index() const noexcept;
|
||
`
|
||
|
||
[6](#range.enumerate.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11031)
|
||
|
||
*Effects*: Equivalent to: return *pos_*;
|
||
|
||
[ð](#lib:operator++,enumerate_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.enumerate.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11042)
|
||
|
||
*Effects*: Equivalent to:++*current_*;++*pos_*;return *this;
|
||
|
||
[ð](#lib:operator++,enumerate_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[8](#range.enumerate.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11058)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.enumerate.iterator-8.sentence-1)
|
||
|
||
[ð](#lib:operator++,enumerate_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[9](#range.enumerate.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11069)
|
||
|
||
*Effects*: Equivalent to:auto temp = *this;++*this;return temp;
|
||
|
||
[ð](#lib:operator--,enumerate_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[10](#range.enumerate.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11085)
|
||
|
||
*Effects*: Equivalent to:--*current_*;--*pos_*;return *this;
|
||
|
||
[ð](#lib:operator--,enumerate_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[11](#range.enumerate.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11101)
|
||
|
||
*Effects*: Equivalent to:auto temp = *this;--*this;return temp;
|
||
|
||
[ð](#lib:operator+=,enumerate_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[12](#range.enumerate.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11118)
|
||
|
||
*Effects*: Equivalent to:*current_* += n;*pos_* += n;return *this;
|
||
|
||
[ð](#lib:operator-=,enumerate_view::iterator)
|
||
|
||
`constexpr iterator& operator-=(difference_type n)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[13](#range.enumerate.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11135)
|
||
|
||
*Effects*: Equivalent to:*current_* -= n;*pos_* -= n;return *this;
|
||
|
||
[ð](#lib:operator==,enumerate_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y) noexcept;
|
||
`
|
||
|
||
[14](#range.enumerate.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11151)
|
||
|
||
*Effects*: Equivalent to: return x.*pos_* == y.*pos_*;
|
||
|
||
[ð](#lib:operator%3c=%3e,enumerate_view::iterator)
|
||
|
||
`friend constexpr strong_ordering operator<=>(const iterator& x, const iterator& y) noexcept;
|
||
`
|
||
|
||
[15](#range.enumerate.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11162)
|
||
|
||
*Effects*: Equivalent to: return x.*pos_* <=> y.*pos_*;
|
||
|
||
[ð](#lib:operator+,enumerate_view::iterator)
|
||
|
||
`friend constexpr iterator operator+(const iterator& x, difference_type y)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[16](#range.enumerate.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11174)
|
||
|
||
*Effects*: Equivalent to:auto temp = x;
|
||
temp += y;return temp;
|
||
|
||
[ð](#lib:operator+,enumerate_view::iterator_)
|
||
|
||
`friend constexpr iterator operator+(difference_type x, const iterator& y)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[17](#range.enumerate.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11191)
|
||
|
||
*Effects*: Equivalent to: return y + x;
|
||
|
||
[ð](#lib:operator-,enumerate_view::iterator)
|
||
|
||
`friend constexpr iterator operator-(const iterator& x, difference_type y)
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[18](#range.enumerate.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11203)
|
||
|
||
*Effects*: Equivalent to:auto temp = x;
|
||
temp -= y;return temp;
|
||
|
||
[ð](#lib:operator-,enumerate_view::iterator_)
|
||
|
||
`friend constexpr difference_type operator-(const iterator& x, const iterator& y) noexcept;
|
||
`
|
||
|
||
[19](#range.enumerate.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11219)
|
||
|
||
*Effects*: Equivalent to: return x.*pos_* - y.*pos_*;
|
||
|
||
#### [25.7.24.4](#range.enumerate.sentinel) Class template enumerate_view::*sentinel* [[range.enumerate.sentinel]](range.enumerate.sentinel)
|
||
|
||
[ð](#lib:enumerate_view::sentinel)
|
||
|
||
namespace std::ranges {template<[view](range.view#concept:view "25.4.5 Views [range.view]") V>requires [*range-with-movable-references*](range.utility.helpers#concept:range-with-movable-references "25.5.2 Helper concepts [range.utility.helpers]")<V>template<bool Const>class enumerate_view<V>::*sentinel* {using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*constexpr explicit *sentinel*(sentinel_t<*Base*> end); // *exposition only*public:*sentinel*() = default; constexpr *sentinel*(*sentinel*<!Const> other)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; constexpr sentinel_t<*Base*> base() const; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *sentinel*& x, const *iterator*<OtherConst>& y); };}
|
||
|
||
[ð](#lib:enumerate_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<Base> end);
|
||
`
|
||
|
||
[1](#range.enumerate.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11267)
|
||
|
||
*Effects*: Initializes *end_* with std::move(end)[.](#range.enumerate.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:enumerate_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> other)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.enumerate.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11279)
|
||
|
||
*Effects*: Initializes *end_* with std::move(other.*end_*)[.](#range.enumerate.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:base,enumerate_view::sentinel)
|
||
|
||
`constexpr sentinel_t<Base> base() const;
|
||
`
|
||
|
||
[3](#range.enumerate.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11290)
|
||
|
||
*Effects*: Equivalent to: return *end_*;
|
||
|
||
[ð](#lib:operator==,enumerate_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[4](#range.enumerate.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11303)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*end_*;
|
||
|
||
[ð](#lib:operator-,enumerate_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[5](#range.enumerate.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11317)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* - y.*end_*;
|
||
|
||
[ð](#lib:operator-,enumerate_view::sentinel_)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
||
`
|
||
|
||
[6](#range.enumerate.sentinel-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11331)
|
||
|
||
*Effects*: Equivalent to: return x.*end_* - y.*current_*;
|
||
|
||
### [25.7.25](#range.zip) Zip view [[range.zip]](range.zip)
|
||
|
||
#### [25.7.25.1](#range.zip.overview) Overview [[range.zip.overview]](range.zip.overview)
|
||
|
||
[1](#range.zip.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11340)
|
||
|
||
zip_view takes any number of views and
|
||
produces a view of tuples of references
|
||
to the corresponding elements of the constituent views[.](#range.zip.overview-1.sentence-1)
|
||
|
||
[2](#range.zip.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11346)
|
||
|
||
The name views::zip denotes
|
||
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))[.](#range.zip.overview-2.sentence-1)
|
||
|
||
Given a pack of subexpressions Es...,
|
||
the expression views::zip(Es...) is expression-equivalent to
|
||
|
||
- [(2.1)](#range.zip.overview-2.1)
|
||
|
||
auto(views::empty<tuple<>>) if Es is an empty pack,
|
||
|
||
- [(2.2)](#range.zip.overview-2.2)
|
||
|
||
otherwise, zip_view<views::all_t<decltype((Es))>...>(Es...)[.](#range.zip.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.zip.overview-example-1)*: vector v = {1, 2};
|
||
list l = {'a', 'b', 'c'};
|
||
|
||
auto z = views::zip(v, l);
|
||
range_reference_t<decltype(z)> f = z.front(); // f is a tuple<int&, char&>// that refers to the first element of v and lfor (auto&& [x, y] : z) { cout << '(' << x << ", " << y << ") "; // prints (1, a) (2, b)} â *end example*]
|
||
|
||
#### [25.7.25.2](#range.zip.view) Class template zip_view [[range.zip.view]](range.zip.view)
|
||
|
||
[ð](#lib:zip_view_)
|
||
|
||
namespace std::ranges {template<class... Rs>concept [*zip-is-common*](#concept:zip-is-common "25.7.25.2 Class template zip_view [range.zip.view]") = // *exposition only*(sizeof...(Rs) == 1 && ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...)) ||(!([bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...) && ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...)) ||(([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...) && ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Rs> && ...)); template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0)class zip_view : public view_interface<zip_view<Views...>> { tuple<Views...> *views_*; // *exposition only*// [[range.zip.iterator]](#range.zip.iterator "25.7.25.3 Class template zip_view::iterator"), class template zip_view::*iterator*template<bool> class *iterator*; // *exposition only*// [[range.zip.sentinel]](#range.zip.sentinel "25.7.25.4 Class template zip_view::sentinel"), class template zip_view::*sentinel*template<bool> class *sentinel*; // *exposition only*public: zip_view() = default; constexpr explicit zip_view(Views... views); constexpr auto begin() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...)) {return *iterator*<false>(*tuple-transform*(ranges::begin, *views_*)); }constexpr auto begin() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) {return *iterator*<true>(*tuple-transform*(ranges::begin, *views_*)); }constexpr auto end() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...)) {if constexpr (<Views...>) {return *sentinel*<false>(*tuple-transform*(ranges::end, *views_*)); } else if constexpr (([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Views> && ...)) {return begin() + iter_difference_t<*iterator*<false>>(size()); } else {return *iterator*<false>(*tuple-transform*(ranges::end, *views_*)); }}constexpr auto end() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) {if constexpr (<const Views...>) {return *sentinel*<true>(*tuple-transform*(ranges::end, *views_*)); } else if constexpr (([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<const Views> && ...)) {return begin() + iter_difference_t<*iterator*<true>>(size()); } else {return *iterator*<true>(*tuple-transform*(ranges::end, *views_*)); }}constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Views> && ...); constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const Views> && ...); }; template<class... Rs> zip_view(Rs&&...) -> zip_view<views::all_t<Rs>...>;}
|
||
|
||
[1](#range.zip.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11439)
|
||
|
||
Two zip_view objects have the same underlying sequence if and only if
|
||
the corresponding elements of *views_* are equal ([[concepts.equality]](concepts.equality "18.2 Equality preservation"))
|
||
and have the same underlying sequence[.](#range.zip.view-1.sentence-1)
|
||
|
||
[*Note [1](#range.zip.view-note-1)*:
|
||
|
||
In particular, comparison of iterators obtained from zip_view objects
|
||
that do not have the same underlying sequence
|
||
is not required to produce meaningful results ([[iterator.concept.forward]](iterator.concept.forward "24.3.4.11 Concept forward_iterator"))[.](#range.zip.view-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:zip_view,constructor)
|
||
|
||
`constexpr explicit zip_view(Views... views);
|
||
`
|
||
|
||
[2](#range.zip.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11455)
|
||
|
||
*Effects*: Initializes *views_* with std::move(views)...[.](#range.zip.view-2.sentence-1)
|
||
|
||
[ð](#lib:size,zip_view)
|
||
|
||
`constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Views> && ...);
|
||
constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const Views> && ...);
|
||
`
|
||
|
||
[3](#range.zip.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11467)
|
||
|
||
*Effects*: Equivalent to:return apply([](auto... sizes) {using CT = *make-unsigned-like-t*<common_type_t<decltype(sizes)...>>; return ranges::min({CT(sizes)...});}, *tuple-transform*(ranges::size, *views_*));
|
||
|
||
#### [25.7.25.3](#range.zip.iterator) Class template zip_view::*iterator* [[range.zip.iterator]](range.zip.iterator)
|
||
|
||
[ð](#lib:zip_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0)template<bool Const>class zip_view<Views...>::*iterator* { tuple<iterator_t<*maybe-const*<Const, Views>>...> *current_*; // *exposition only*constexpr explicit *iterator*(tuple<iterator_t<*maybe-const*<Const, Views>>...>); // *exposition only*public:using iterator_category = input_iterator_tag; // not always presentusing iterator_concept = *see below*; using value_type = tuple<range_value_t<*maybe-const*<Const, Views>>...>; using difference_type = common_type_t<range_difference_t<*maybe-const*<Const, Views>>...>; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...); constexpr auto operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator--() requires [*all-bidirectional*](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; constexpr *iterator* operator--(int) requires [*all-bidirectional*](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator+=(difference_type x)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator-=(difference_type x)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; constexpr auto operator[](difference_type n) constrequires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires ([equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<*maybe-const*<Const, Views>>> && ...); friend constexpr auto operator<=>(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr *iterator* operator+(const *iterator*& i, difference_type n)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr *iterator* operator+(difference_type n, const *iterator*& i)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; friend constexpr *iterator* operator-(const *iterator*& i, difference_type n)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>; 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<*maybe-const*<Const, Views>>,
|
||
iterator_t<*maybe-const*<Const, Views>>> && ...); friend constexpr auto iter_move(const *iterator*& i) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& l, const *iterator*& r) noexcept(*see below*)requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, Views>>> && ...); };}
|
||
|
||
[1](#range.zip.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11540)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.zip.iterator-1.1)
|
||
|
||
If [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is modeled,
|
||
then iterator_concept denotes random_access_iterator_tag[.](#range.zip.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.zip.iterator-1.2)
|
||
|
||
Otherwise,
|
||
if [*all-bidirectional*](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is modeled,
|
||
then iterator_concept denotes bidirectional_iterator_tag[.](#range.zip.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.zip.iterator-1.3)
|
||
|
||
Otherwise,
|
||
if [*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is modeled,
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.zip.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.zip.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.zip.iterator-1.4.sentence-1)
|
||
|
||
[2](#range.zip.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11558)
|
||
|
||
*iterator*::iterator_category is present
|
||
if and only if [*all-forward*](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is modeled[.](#range.zip.iterator-2.sentence-1)
|
||
|
||
[3](#range.zip.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11562)
|
||
|
||
If the invocation of any non-const member function of *iterator* exits via an exception,
|
||
the iterator acquires a singular value[.](#range.zip.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:zip_view::iterator,constructor)
|
||
|
||
`constexpr explicit iterator(tuple<iterator_t<maybe-const<Const, Views>>...> current);
|
||
`
|
||
|
||
[4](#range.zip.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11573)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current)[.](#range.zip.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:zip_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...);
|
||
`
|
||
|
||
[5](#range.zip.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11585)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*)[.](#range.zip.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:operator*,izip_view::iterator)
|
||
|
||
`constexpr auto operator*() const;
|
||
`
|
||
|
||
[6](#range.zip.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11596)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*([](auto& i) -> decltype(auto) { return *i; }, *current_*);
|
||
|
||
[ð](#lib:operator++,izip_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.zip.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11610)
|
||
|
||
*Effects*: Equivalent to:*tuple-for-each*([](auto& i) { ++i; }, *current_*);return *this;
|
||
|
||
[ð](#lib:operator++,izip_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[8](#range.zip.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11625)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.zip.iterator-8.sentence-1)
|
||
|
||
[ð](#lib:operator++,izip_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [all-forward](#concept:all-forward "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[9](#range.zip.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11636)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,izip_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [all-bidirectional](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[10](#range.zip.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11652)
|
||
|
||
*Effects*: Equivalent to:*tuple-for-each*([](auto& i) { --i; }, *current_*);return *this;
|
||
|
||
[ð](#lib:operator--,izip_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [all-bidirectional](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[11](#range.zip.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11667)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,izip_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type x)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[12](#range.zip.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11684)
|
||
|
||
*Effects*: Equivalent to:*tuple-for-each*([&]<class I>(I& i) { i += iter_difference_t<I>(x); }, *current_*);return *this;
|
||
|
||
[ð](#lib:operator-=,izip_view::iterator)
|
||
|
||
`constexpr iterator& operator-=(difference_type x)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[13](#range.zip.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11700)
|
||
|
||
*Effects*: Equivalent to:*tuple-for-each*([&]<class I>(I& i) { i -= iter_difference_t<I>(x); }, *current_*);return *this;
|
||
|
||
[ð](#lib:operator%5b%5d,izip_view::iterator)
|
||
|
||
`constexpr auto operator[](difference_type n) const
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[14](#range.zip.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11716)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*([&]<class I>(I& i) -> decltype(auto) {return i[iter_difference_t<I>(n)];}, *current_*);
|
||
|
||
[ð](#lib:operator==,izip_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires ([equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<maybe-const<Const, Views>>> && ...);
|
||
`
|
||
|
||
[15](#range.zip.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11733)
|
||
|
||
*Returns*:
|
||
|
||
- [(15.1)](#range.zip.iterator-15.1)
|
||
|
||
x.*current_* == y.*current_* if [*all-bidirectional*](#concept:all-bidirectional "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...> is true[.](#range.zip.iterator-15.1.sentence-1)
|
||
|
||
- [(15.2)](#range.zip.iterator-15.2)
|
||
|
||
Otherwise, true if there exists an integer 0â¤i<sizeof...(Views) such that bool(std::get<i>(x.*current_*) == std::get<i>(y.*current_*)) is true[.](#range.zip.iterator-15.2.sentence-1)
|
||
[*Note [1](#range.zip.iterator-note-1)*:
|
||
This allows zip_view to model [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]") when all constituent views model [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")[.](#range.zip.iterator-15.2.sentence-2)
|
||
â *end note*]
|
||
|
||
- [(15.3)](#range.zip.iterator-15.3)
|
||
|
||
Otherwise, false[.](#range.zip.iterator-15.3.sentence-1)
|
||
|
||
[ð](#lib:operator%3c=%3e,izip_view::iterator)
|
||
|
||
`friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[16](#range.zip.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11760)
|
||
|
||
*Returns*: x.*current_* <=> y.*current_*[.](#range.zip.iterator-16.sentence-1)
|
||
|
||
[ð](#lib:operator+,izip_view::iterator)
|
||
|
||
`friend constexpr iterator operator+(const iterator& i, difference_type n)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
friend constexpr iterator operator+(difference_type n, const iterator& i)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[17](#range.zip.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11774)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r += n;return r;
|
||
|
||
[ð](#lib:operator-,izip_view::iterator)
|
||
|
||
`friend constexpr iterator operator-(const iterator& i, difference_type n)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, Views...>;
|
||
`
|
||
|
||
[18](#range.zip.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11791)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r -= n;return r;
|
||
|
||
[ð](#lib:operator-,izip_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<maybe-const<Const, Views>>,
|
||
iterator_t<maybe-const<Const, Views>>> && ...);
|
||
`
|
||
|
||
[19](#range.zip.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11809)
|
||
|
||
Let *DIST*(i) be difference_type(std::get<i>(x.*current_*) - std::get<i>(y.*current_*))[.](#range.zip.iterator-19.sentence-1)
|
||
|
||
[20](#range.zip.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11812)
|
||
|
||
*Returns*: The value with the smallest absolute value among *DIST*(n) for all integers 0â¤n<sizeof...(Views)[.](#range.zip.iterator-20.sentence-1)
|
||
|
||
[ð](#lib:iter_move,izip_view::iterator)
|
||
|
||
`friend constexpr auto iter_move(const iterator& i) noexcept(see below);
|
||
`
|
||
|
||
[21](#range.zip.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11824)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*(ranges::iter_move, i.*current_*);
|
||
|
||
[22](#range.zip.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11831)
|
||
|
||
*Remarks*: The exception specification is equivalent to:(noexcept(ranges::iter_move(declval<const iterator_t<*maybe-const*<Const,
|
||
Views>>&>())) && ...) &&(is_nothrow_move_constructible_v<range_rvalue_reference_t<*maybe-const*<Const,
|
||
Views>>> && ...)
|
||
|
||
[ð](#lib:iter_swap,izip_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
|
||
requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<maybe-const<Const, Views>>> && ...);
|
||
`
|
||
|
||
[23](#range.zip.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11849)
|
||
|
||
*Effects*: For every integer 0â¤i<sizeof...(Views),
|
||
performs:ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))
|
||
|
||
[24](#range.zip.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11857)
|
||
|
||
*Remarks*: The exception specification is equivalent to
|
||
the logical and of the following expressions:noexcept(ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))) for every integer 0â¤i<sizeof...(Views)[.](#range.zip.iterator-24.sentence-1)
|
||
|
||
#### [25.7.25.4](#range.zip.sentinel) Class template zip_view::*sentinel* [[range.zip.sentinel]](range.zip.sentinel)
|
||
|
||
[ð](#lib:zip_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0)template<bool Const>class zip_view<Views...>::*sentinel* { tuple<sentinel_t<*maybe-const*<Const, Views>>...> *end_*; // *exposition only*constexpr explicit *sentinel*(tuple<sentinel_t<*maybe-const*<Const, Views>>...> end); // *exposition only*public:*sentinel*() = default; constexpr *sentinel*(*sentinel*<!Const> i)requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<Views>, sentinel_t<const Views>> && ...); template<bool OtherConst>requires ([sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
|
||
iterator_t<*maybe-const*<OtherConst, Views>>> && ...)friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
|
||
iterator_t<*maybe-const*<OtherConst, Views>>> && ...)friend constexpr common_type_t<range_difference_t<*maybe-const*<OtherConst, Views>>...>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
|
||
iterator_t<*maybe-const*<OtherConst, Views>>> && ...)friend constexpr common_type_t<range_difference_t<*maybe-const*<OtherConst, Views>>...>operator-(const *sentinel*& y, const *iterator*<OtherConst>& x); };}
|
||
|
||
[ð](#lib:zip_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(tuple<sentinel_t<maybe-const<Const, Views>>...> end);
|
||
`
|
||
|
||
[1](#range.zip.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11910)
|
||
|
||
*Effects*: Initializes *end_* with end[.](#range.zip.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:zip_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> i)
|
||
requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<Views>, sentinel_t<const Views>> && ...);
|
||
`
|
||
|
||
[2](#range.zip.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11922)
|
||
|
||
*Effects*: Initializes *end_* with std::move(i.*end_*)[.](#range.zip.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,zip_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires ([sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<maybe-const<Const, Views>>,
|
||
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.zip.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11936)
|
||
|
||
*Returns*: true if there exists an integer 0â¤i<sizeof...(Views) such that bool(std::get<i>(x.*current_*) == std::get<i>(y.*end_*)) is true[.](#range.zip.sentinel-3.sentence-1)
|
||
|
||
Otherwise, false[.](#range.zip.sentinel-3.sentence-2)
|
||
|
||
[ð](#lib:operator-,zip_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<maybe-const<Const, Views>>,
|
||
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
||
friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[4](#range.zip.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11954)
|
||
|
||
Let D be the return type[.](#range.zip.sentinel-4.sentence-1)
|
||
|
||
Let *DIST*(i) beD(std::get<i>(x.*current_*) - std::get<i>(y.*end_*))[.](#range.zip.sentinel-4.sentence-2)
|
||
|
||
[5](#range.zip.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11959)
|
||
|
||
*Returns*: The value with the smallest absolute value among *DIST*(n) for all integers 0â¤n<sizeof...(Views)[.](#range.zip.sentinel-5.sentence-1)
|
||
|
||
[ð](#lib:operator-,zip_view::sentinel_)
|
||
|
||
`template<bool OtherConst>
|
||
requires ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<maybe-const<Const, Views>>,
|
||
iterator_t<maybe-const<OtherConst, Views>>> && ...)
|
||
friend constexpr common_type_t<range_difference_t<maybe-const<OtherConst, Views>>...>
|
||
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
||
`
|
||
|
||
[6](#range.zip.sentinel-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11975)
|
||
|
||
*Effects*: Equivalent to: return -(x - y);
|
||
|
||
### [25.7.26](#range.zip.transform) Zip transform view [[range.zip.transform]](range.zip.transform)
|
||
|
||
#### [25.7.26.1](#range.zip.transform.overview) Overview [[range.zip.transform.overview]](range.zip.transform.overview)
|
||
|
||
[1](#range.zip.transform.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11984)
|
||
|
||
zip_transform_view takes an invocable object and
|
||
any number of views and
|
||
produces a view
|
||
whose Mth element is
|
||
the result of applying the invocable object
|
||
to the Mth elements of all views[.](#range.zip.transform.overview-1.sentence-1)
|
||
|
||
[2](#range.zip.transform.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11993)
|
||
|
||
The name views::zip_transform denotes
|
||
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))[.](#range.zip.transform.overview-2.sentence-1)
|
||
|
||
Let F be a subexpression, and
|
||
let Es... be a pack of subexpressions[.](#range.zip.transform.overview-2.sentence-2)
|
||
|
||
- [(2.1)](#range.zip.transform.overview-2.1)
|
||
|
||
If Es is an empty pack,
|
||
let FD be decay_t<decltype((F))>[.](#range.zip.transform.overview-2.1.sentence-1)
|
||
|
||
* [(2.1.1)](#range.zip.transform.overview-2.1.1)
|
||
|
||
If [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<FD> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<FD&> is false, or
|
||
if decay_t<invoke_result_t<FD&>> is not an object type,views::zip_transform(F, Es...) is ill-formed.
|
||
|
||
* [(2.1.2)](#range.zip.transform.overview-2.1.2)
|
||
|
||
Otherwise, the expression views::zip_transform(F, Es...) is expression-equivalent to((void)F, auto(views::empty<decay_t<invoke_result_t<FD&>>>))
|
||
|
||
- [(2.2)](#range.zip.transform.overview-2.2)
|
||
|
||
Otherwise, the expression views::zip_transform(F, Es...) is expression-equivalent to zip_transform_view(F, Es...)[.](#range.zip.transform.overview-2.2.sentence-1)
|
||
|
||
[3](#range.zip.transform.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12021)
|
||
|
||
[*Example [1](#range.zip.transform.overview-example-1)*: vector v1 = {1, 2};
|
||
vector v2 = {4, 5, 6};
|
||
|
||
for (auto i : views::zip_transform(plus(), v1, v2)) { cout << i << ' '; // prints 5 7} â *end example*]
|
||
|
||
#### [25.7.26.2](#range.zip.transform.view) Class template zip_transform_view [[range.zip.transform.view]](range.zip.transform.view)
|
||
|
||
[ð](#lib:zip_transform_view_)
|
||
|
||
namespace std::ranges {template<[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, range_reference_t<Views>...> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, range_reference_t<Views>...>>class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> {*movable-box*<F> *fun_*; // *exposition only* zip_view<Views...> *zip_*; // *exposition only*using *InnerView* = zip_view<Views...>; // *exposition only*template<bool Const>using *ziperator* = iterator_t<*maybe-const*<Const, *InnerView*>>; // *exposition only*template<bool Const>using *zentinel* = sentinel_t<*maybe-const*<Const, *InnerView*>>; // *exposition only*// [[range.zip.transform.iterator]](#range.zip.transform.iterator "25.7.26.3 Class template zip_transform_view::iterator"), class template zip_transform_view::*iterator*template<bool> class *iterator*; // *exposition only*// [[range.zip.transform.sentinel]](#range.zip.transform.sentinel "25.7.26.4 Class template zip_transform_view::sentinel"), class template zip_transform_view::*sentinel*template<bool> class *sentinel*; // *exposition only*public: zip_transform_view() = default; constexpr explicit zip_transform_view(F fun, Views... views); constexpr auto begin() { return *iterator*<false>(*this, *zip_*.begin()); }constexpr auto begin() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const *InnerView*> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const Views>...> {return *iterator*<true>(*this, *zip_*.begin()); }constexpr auto end() {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*InnerView*>) {return *iterator*<false>(*this, *zip_*.end()); } else {return *sentinel*<false>(*zip_*.end()); }}constexpr auto end() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const *InnerView*> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, range_reference_t<const Views>...> {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const *InnerView*>) {return *iterator*<true>(*this, *zip_*.end()); } else {return *sentinel*<true>(*zip_*.end()); }}constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<*InnerView*> {return *zip_*.size(); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const *InnerView*> {return *zip_*.size(); }}; template<class F, class... Rs> zip_transform_view(F, Rs&&...) -> zip_transform_view<F, views::all_t<Rs>...>;}
|
||
|
||
[ð](#lib:zip_transform_view,constructor)
|
||
|
||
`constexpr explicit zip_transform_view(F fun, Views... views);
|
||
`
|
||
|
||
[1](#range.zip.transform.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12112)
|
||
|
||
*Effects*: Initializes *fun_* with std::move(fun) and*zip_* with std::move(views)...[.](#range.zip.transform.view-1.sentence-1)
|
||
|
||
#### [25.7.26.3](#range.zip.transform.iterator) Class template zip_transform_view::*iterator* [[range.zip.transform.iterator]](range.zip.transform.iterator)
|
||
|
||
[ð](#lib:zip_transform_view::iterator)
|
||
|
||
namespace std::ranges {template<[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, range_reference_t<Views>...> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, range_reference_t<Views>...>>template<bool Const>class zip_transform_view<F, Views...>::*iterator* {using *Parent* = *maybe-const*<Const, zip_transform_view>; // *exposition only*using *Base* = *maybe-const*<Const, *InnerView*>; // *exposition only**Parent** *parent_* = nullptr; // *exposition only**ziperator*<Const> *inner_*; // *exposition only*constexpr *iterator*(*Parent*& parent, *ziperator*<Const> inner); // *exposition only*public:using iterator_category = *see below*; // not always presentusing iterator_concept = typename *ziperator*<Const>::iterator_concept; using value_type = remove_cvref_t<invoke_result_t<*maybe-const*<Const, F>&,
|
||
range_reference_t<*maybe-const*<Const, Views>>...>>; using difference_type = range_difference_t<*Base*>; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<*ziperator*<false>, *ziperator*<Const>>; constexpr decltype(auto) operator*() const noexcept(*see below*); constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; 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 decltype(auto) 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)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<*ziperator*<Const>>; 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*>; 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]")<*ziperator*<Const>, *ziperator*<Const>>; };}
|
||
|
||
[1](#range.zip.transform.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12180)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*iterator*::iterator_category is defined if and only if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.zip.transform.iterator-1.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
|
||
- [(1.1)](#range.zip.transform.iterator-1.1)
|
||
|
||
Ifinvoke_result_t<*maybe-const*<Const, F>&, range_reference_t<*maybe-const*<Const, Views>>...> is not a reference,iterator_category denotes input_iterator_tag.
|
||
|
||
- [(1.2)](#range.zip.transform.iterator-1.2)
|
||
|
||
Otherwise, let Cs denote the pack of typesiterator_traits<iterator_t<*maybe-const*<Const, Views>>>::iterator_category.... * [(1.2.1)](#range.zip.transform.iterator-1.2.1)
|
||
|
||
If ([derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<Cs, random_access_iterator_tag> && ...) is true,iterator_category denotes random_access_iterator_tag[.](#range.zip.transform.iterator-1.2.1.sentence-1)
|
||
|
||
* [(1.2.2)](#range.zip.transform.iterator-1.2.2)
|
||
|
||
Otherwise,
|
||
if ([derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<Cs, bidirectional_iterator_tag> && ...) is true,iterator_category denotes bidirectional_iterator_tag[.](#range.zip.transform.iterator-1.2.2.sentence-1)
|
||
|
||
* [(1.2.3)](#range.zip.transform.iterator-1.2.3)
|
||
|
||
Otherwise,
|
||
if ([derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<Cs, forward_iterator_tag> && ...) is true,iterator_category denotes forward_iterator_tag[.](#range.zip.transform.iterator-1.2.3.sentence-1)
|
||
|
||
* [(1.2.4)](#range.zip.transform.iterator-1.2.4)
|
||
|
||
Otherwise, iterator_category denotes input_iterator_tag[.](#range.zip.transform.iterator-1.2.4.sentence-1)
|
||
|
||
[ð](#lib:zip_transform_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent& parent, ziperator<Const> inner);
|
||
`
|
||
|
||
[2](#range.zip.transform.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12223)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent) and*inner_* with std::move(inner)[.](#range.zip.transform.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:zip_transform_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<ziperator<false>, ziperator<Const>>;
|
||
`
|
||
|
||
[3](#range.zip.transform.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12236)
|
||
|
||
*Effects*: Initializes *parent_* with i.*parent_* and*inner_* with std::move(i.*inner_*)[.](#range.zip.transform.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:operator*,zip_transform_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator*() const noexcept(see below);
|
||
`
|
||
|
||
[4](#range.zip.transform.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12248)
|
||
|
||
*Effects*: Equivalent to:return apply([&](const auto&... iters) -> decltype(auto) {return invoke(**parent_*->*fun_*, *iters...);}, *inner_*.*current_*);
|
||
|
||
[5](#range.zip.transform.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12257)
|
||
|
||
*Remarks*: Let Is be the pack 0, 1, …, (sizeof...(Views) - 1)[.](#range.zip.transform.iterator-5.sentence-1)
|
||
|
||
The exception specification is equivalent to:noexcept(invoke(**parent_*->*fun_*, *std::get<Is>(*inner_*.*current_*)...))[.](#range.zip.transform.iterator-5.sentence-2)
|
||
|
||
[ð](#lib:operator++,zip_transform_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[6](#range.zip.transform.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12270)
|
||
|
||
*Effects*: Equivalent to:++*inner_*;return *this;
|
||
|
||
[ð](#lib:operator++,zip_transform_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[7](#range.zip.transform.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12285)
|
||
|
||
*Effects*: Equivalent to: ++*this[.](#range.zip.transform.iterator-7.sentence-1)
|
||
|
||
[ð](#lib:operator++,zip_transform_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[8](#range.zip.transform.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12296)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,zip_transform_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[9](#range.zip.transform.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12312)
|
||
|
||
*Effects*: Equivalent to:--*inner_*;return *this;
|
||
|
||
[ð](#lib:operator--,zip_transform_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[10](#range.zip.transform.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12327)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,zip_transform_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]")<Base>;
|
||
`
|
||
|
||
[11](#range.zip.transform.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12344)
|
||
|
||
*Effects*: Equivalent to:*inner_* += x;return *this;
|
||
|
||
[ð](#lib:operator+=,zip_transform_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]")<Base>;
|
||
`
|
||
|
||
[12](#range.zip.transform.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12360)
|
||
|
||
*Effects*: Equivalent to:*inner_* -= x;return *this;
|
||
|
||
[ð](#lib:operator%5b%5d,zip_transform_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator[](difference_type n) const
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[13](#range.zip.transform.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12376)
|
||
|
||
*Effects*: Equivalent to:return apply([&]<class... Is>(const Is&... iters) -> decltype(auto) {return invoke(**parent_*->*fun_*, iters[iter_difference_t<Is>(n)]...);}, *inner_*.*current_*);
|
||
|
||
[ð](#lib:operator==,zip_transform_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<ziperator<Const>>;
|
||
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>;
|
||
`
|
||
|
||
[14](#range.zip.transform.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12395)
|
||
|
||
Let *op* be the operator[.](#range.zip.transform.iterator-14.sentence-1)
|
||
|
||
[15](#range.zip.transform.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12398)
|
||
|
||
*Effects*: Equivalent to:return x.*inner_* *op* y.*inner_*;
|
||
|
||
[ð](#lib:operator+,zip_transform_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]")<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>;
|
||
`
|
||
|
||
[16](#range.zip.transform.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12413)
|
||
|
||
*Effects*: Equivalent to:return *iterator*(*i.*parent_*, i.*inner_* + n);
|
||
|
||
[ð](#lib:operator-,zip_transform_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]")<Base>;
|
||
`
|
||
|
||
[17](#range.zip.transform.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12426)
|
||
|
||
*Effects*: Equivalent to:return *iterator*(*i.*parent_*, i.*inner_* - n);
|
||
|
||
[ð](#lib:operator-,zip_transform_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]")<ziperator<Const>, ziperator<Const>>;
|
||
`
|
||
|
||
[18](#range.zip.transform.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12439)
|
||
|
||
*Effects*: Equivalent to:return x.*inner_* - y.*inner_*;
|
||
|
||
#### [25.7.26.4](#range.zip.transform.sentinel) Class template zip_transform_view::*sentinel* [[range.zip.transform.sentinel]](range.zip.transform.sentinel)
|
||
|
||
[ð](#lib:zip_transform_view::sentinel)
|
||
|
||
namespace std::ranges {template<[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, range_reference_t<Views>...> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, range_reference_t<Views>...>>template<bool Const>class zip_transform_view<F, Views...>::*sentinel* {*zentinel*<Const> *inner_*; // *exposition only*constexpr explicit *sentinel*(*zentinel*<Const> inner); // *exposition only*public:*sentinel*() = default; constexpr *sentinel*(*sentinel*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<*zentinel*<false>, *zentinel*<Const>>; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<*zentinel*<Const>, *ziperator*<OtherConst>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<*zentinel*<Const>, *ziperator*<OtherConst>>friend constexpr range_difference_t<*maybe-const*<OtherConst, *InnerView*>>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<*zentinel*<Const>, *ziperator*<OtherConst>>friend constexpr range_difference_t<*maybe-const*<OtherConst, *InnerView*>>operator-(const *sentinel*& x, const *iterator*<OtherConst>& y); };}
|
||
|
||
[ð](#lib:zip_transform_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(zentinel<Const> inner);
|
||
`
|
||
|
||
[1](#range.zip.transform.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12487)
|
||
|
||
*Effects*: Initializes *inner_* with inner[.](#range.zip.transform.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:zip_transform_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<zentinel<false>, zentinel<Const>>;
|
||
`
|
||
|
||
[2](#range.zip.transform.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12499)
|
||
|
||
*Effects*: Initializes *inner_* with std::move(i.*inner_*)[.](#range.zip.transform.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,zip_transform_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<zentinel<Const>, ziperator<OtherConst>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.zip.transform.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12512)
|
||
|
||
*Effects*: Equivalent to: return x.*inner_* == y.*inner_*;
|
||
|
||
[ð](#lib:operator-,zip_transform_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<zentinel<Const>, ziperator<OtherConst>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<zentinel<Const>, ziperator<OtherConst>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
||
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
||
`
|
||
|
||
[4](#range.zip.transform.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12530)
|
||
|
||
*Effects*: Equivalent to: return x.*inner_* - y.*inner_*;
|
||
|
||
### [25.7.27](#range.adjacent) Adjacent view [[range.adjacent]](range.adjacent)
|
||
|
||
#### [25.7.27.1](#range.adjacent.overview) Overview [[range.adjacent.overview]](range.adjacent.overview)
|
||
|
||
[1](#range.adjacent.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12539)
|
||
|
||
adjacent_view takes a view and
|
||
produces a view whose Mth element is
|
||
a tuple of references to
|
||
the Mth through (M+Nâ1)th elements of
|
||
the original view[.](#range.adjacent.overview-1.sentence-1)
|
||
|
||
If the original view has fewer than N elements, the resulting view is empty[.](#range.adjacent.overview-1.sentence-2)
|
||
|
||
[2](#range.adjacent.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12547)
|
||
|
||
The name views::adjacent<N> denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.adjacent.overview-2.sentence-1)
|
||
|
||
Given a subexpression E and a constant expression N,
|
||
the expression views::adjacent<N>(E) is expression-equivalent to
|
||
|
||
- [(2.1)](#range.adjacent.overview-2.1)
|
||
|
||
((void)E, auto(views::empty<tuple<>>)) if N is equal to 0 anddecltype((E)) models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
|
||
- [(2.2)](#range.adjacent.overview-2.2)
|
||
|
||
otherwise, adjacent_view<views::all_t<decltype((E))>, N>(E)[.](#range.adjacent.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.adjacent.overview-example-1)*: vector v = {1, 2, 3, 4};
|
||
|
||
for (auto i : v | views::adjacent<2>) { cout << "(" << std::get<0>(i) << ", " << std::get<1>(i) << ") "; // prints (1, 2) (2, 3) (3, 4)} â *end example*]
|
||
|
||
[3](#range.adjacent.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12572)
|
||
|
||
Define *REPEAT*(T, N) as a pack of N types,
|
||
each of which denotes the same type as T[.](#range.adjacent.overview-3.sentence-1)
|
||
|
||
#### [25.7.27.2](#range.adjacent.view) Class template adjacent_view [[range.adjacent.view]](range.adjacent.view)
|
||
|
||
[ð](#lib:adjacent_view)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && (N > 0)class adjacent_view : public view_interface<adjacent_view<V, N>> { V *base_* = V(); // *exposition only*// [[range.adjacent.iterator]](#range.adjacent.iterator "25.7.27.3 Class template adjacent_view::iterator"), class template adjacent_view::*iterator*template<bool> class *iterator*; // *exposition only*// [[range.adjacent.sentinel]](#range.adjacent.sentinel "25.7.27.4 Class template adjacent_view::sentinel"), class template adjacent_view::*sentinel*template<bool> class *sentinel*; // *exposition only*struct *as-sentinel*{}; // *exposition only*public: adjacent_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit adjacent_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>) {return *iterator*<false>(ranges::begin(*base_*), ranges::end(*base_*)); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {return *iterator*<true>(ranges::begin(*base_*), ranges::end(*base_*)); }constexpr auto end() requires (<V>) {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>) {return *iterator*<false>(*as-sentinel*{}, ranges::begin(*base_*), ranges::end(*base_*)); } else {return *sentinel*<false>(ranges::end(*base_*)); }}constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V>) {return *iterator*<true>(*as-sentinel*{}, ranges::begin(*base_*), ranges::end(*base_*)); } else {return *sentinel*<true>(ranges::end(*base_*)); }}constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; 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]")<const V>; };}
|
||
|
||
[ð](#lib:adjacent_view,constructor)
|
||
|
||
`constexpr explicit adjacent_view(V base);
|
||
`
|
||
|
||
[1](#range.adjacent.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12642)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.adjacent.view-1.sentence-1)
|
||
|
||
[ð](#lib:size,adjacent_view)
|
||
|
||
`constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[2](#range.adjacent.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12654)
|
||
|
||
*Effects*: Equivalent to:using ST = decltype(ranges::size(*base_*));using CT = common_type_t<ST, size_t>;auto sz = static_cast<CT>(ranges::size(*base_*));
|
||
sz -= std::min<CT>(sz, N - 1);return static_cast<ST>(sz);
|
||
|
||
[ð](#lib:reserve_hint,adjacent_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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[3](#range.adjacent.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12673)
|
||
|
||
*Effects*: Equivalent to:using DT = range_difference_t<decltype((*base_*))>;using CT = common_type_t<DT, size_t>;auto sz = static_cast<CT>(ranges::reserve_hint(*base_*));
|
||
sz -= std::min<CT>(sz, N - 1);return *to-unsigned-like*(sz);
|
||
|
||
#### [25.7.27.3](#range.adjacent.iterator) Class template adjacent_view::*iterator* [[range.adjacent.iterator]](range.adjacent.iterator)
|
||
|
||
[ð](#lib:adjacent_view::iterator)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && (N > 0)template<bool Const>class adjacent_view<V, N>::*iterator* {using *Base* = *maybe-const*<Const, V>; // *exposition only* array<iterator_t<*Base*>, N> *current_* = array<iterator_t<*Base*>, N>(); // *exposition only*constexpr *iterator*(iterator_t<*Base*> first, sentinel_t<*Base*> last); // *exposition only*constexpr *iterator*(*as-sentinel*, iterator_t<*Base*> first, iterator_t<*Base*> last); // *exposition only*public:using iterator_category = input_iterator_tag; using iterator_concept = *see below*; using value_type = tuple<*REPEAT*(range_value_t<*Base*>, N)...>; using difference_type = range_difference_t<*Base*>; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr auto 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 auto 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, 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]")<iterator_t<*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 *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*>, iterator_t<*Base*>>; friend constexpr auto iter_move(const *iterator*& i) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& l, const *iterator*& r) noexcept(*see below*)requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.adjacent.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12753)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.adjacent.iterator-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[.](#range.adjacent.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.adjacent.iterator-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[.](#range.adjacent.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.adjacent.iterator-1.3)
|
||
|
||
Otherwise, iterator_concept denotes forward_iterator_tag[.](#range.adjacent.iterator-1.3.sentence-1)
|
||
|
||
[2](#range.adjacent.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12766)
|
||
|
||
If the invocation of any non-const member function of *iterator* exits via an exception, the *iterator* acquires a singular value[.](#range.adjacent.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:adjacent_view::iterator,constructor)
|
||
|
||
`constexpr iterator(iterator_t<Base> first, sentinel_t<Base> last);
|
||
`
|
||
|
||
[3](#range.adjacent.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12776)
|
||
|
||
*Postconditions*: *current_*[0] == first is true, and
|
||
for every integer 1â¤i<N,*current_*[i] == ranges::next(*current_*[i-1], 1, last) is true[.](#range.adjacent.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:adjacent_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(as-sentinel, iterator_t<Base> first, iterator_t<Base> last);
|
||
`
|
||
|
||
[4](#range.adjacent.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12790)
|
||
|
||
*Postconditions*: If *Base* does not model [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"),
|
||
each element of *current_* is equal to *last*[.](#range.adjacent.iterator-4.sentence-1)
|
||
|
||
Otherwise, *current_*[N-1] == last is true, and
|
||
for every integer 0â¤i<(Nâ1),*current_*[i] == ranges::prev(*current_*[i+1], 1, first) is true[.](#range.adjacent.iterator-4.sentence-2)
|
||
|
||
[ð](#lib:adjacent_view::iterator,constructor__)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[5](#range.adjacent.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12807)
|
||
|
||
*Effects*: Initializes each element of *current_* with the corresponding element of i.*current_* as an xvalue[.](#range.adjacent.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:operator*,adjacent_view::iterator)
|
||
|
||
`constexpr auto operator*() const;
|
||
`
|
||
|
||
[6](#range.adjacent.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12819)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*([](auto& i) -> decltype(auto) { return *i; }, *current_*);
|
||
|
||
[ð](#lib:operator++,adjacent_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.adjacent.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12833)
|
||
|
||
*Preconditions*: *current_*.back() is incrementable[.](#range.adjacent.iterator-7.sentence-1)
|
||
|
||
[8](#range.adjacent.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12837)
|
||
|
||
*Postconditions*: Each element of *current_* is equal to ranges::next(i),
|
||
where i is the value of that element before the call[.](#range.adjacent.iterator-8.sentence-1)
|
||
|
||
[9](#range.adjacent.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12842)
|
||
|
||
*Returns*: *this[.](#range.adjacent.iterator-9.sentence-1)
|
||
|
||
[ð](#lib:operator++,adjacent_view::iterator_)
|
||
|
||
`constexpr iterator operator++(int);
|
||
`
|
||
|
||
[10](#range.adjacent.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12853)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,adjacent_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[11](#range.adjacent.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12869)
|
||
|
||
*Preconditions*: *current_*.front() is decrementable[.](#range.adjacent.iterator-11.sentence-1)
|
||
|
||
[12](#range.adjacent.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12873)
|
||
|
||
*Postconditions*: Each element of *current_* is equal to ranges::prev(i),
|
||
where i is the value of that element before the call[.](#range.adjacent.iterator-12.sentence-1)
|
||
|
||
[13](#range.adjacent.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12878)
|
||
|
||
*Returns*: *this[.](#range.adjacent.iterator-13.sentence-1)
|
||
|
||
[ð](#lib:operator--,adjacent_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[14](#range.adjacent.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12889)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[15](#range.adjacent.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12906)
|
||
|
||
*Preconditions*: *current_*.back() + x has well-defined behavior[.](#range.adjacent.iterator-15.sentence-1)
|
||
|
||
[16](#range.adjacent.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12910)
|
||
|
||
*Postconditions*: Each element of *current_* is equal to i + x,
|
||
where i is the value of that element before the call[.](#range.adjacent.iterator-16.sentence-1)
|
||
|
||
[17](#range.adjacent.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12915)
|
||
|
||
*Returns*: *this[.](#range.adjacent.iterator-17.sentence-1)
|
||
|
||
[ð](#lib:operator-=,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[18](#range.adjacent.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12927)
|
||
|
||
*Preconditions*: *current_*.front() - x has well-defined behavior[.](#range.adjacent.iterator-18.sentence-1)
|
||
|
||
[19](#range.adjacent.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12931)
|
||
|
||
*Postconditions*: Each element of *current_* is equal to i - x,
|
||
where i is the value of that element before the call[.](#range.adjacent.iterator-19.sentence-1)
|
||
|
||
[20](#range.adjacent.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12936)
|
||
|
||
*Returns*: *this[.](#range.adjacent.iterator-20.sentence-1)
|
||
|
||
[ð](#lib:operator%5b%5d,adjacent_view::iterator)
|
||
|
||
`constexpr auto operator[](difference_type n) const
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[21](#range.adjacent.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12948)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*([&](auto& i) -> decltype(auto) { return i[n]; }, *current_*);
|
||
|
||
[ð](#lib:operator==,adjacent_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y);
|
||
`
|
||
|
||
[22](#range.adjacent.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12962)
|
||
|
||
*Returns*: x.*current_*.back() == y.*current_*.back()[.](#range.adjacent.iterator-22.sentence-1)
|
||
|
||
[ð](#lib:operator%3c,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[23](#range.adjacent.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12974)
|
||
|
||
*Returns*: x.*current_*.back() < y.*current_*.back()[.](#range.adjacent.iterator-23.sentence-1)
|
||
|
||
[ð](#lib:operator%3e,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[24](#range.adjacent.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12986)
|
||
|
||
*Effects*: Equivalent to: return y < x;
|
||
|
||
[ð](#lib:operator%3c=,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[25](#range.adjacent.iterator-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L12998)
|
||
|
||
*Effects*: Equivalent to: return !(y < x);
|
||
|
||
[ð](#lib:operator%3e=,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[26](#range.adjacent.iterator-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13010)
|
||
|
||
*Effects*: Equivalent to: return !(x < y);
|
||
|
||
[ð](#lib:operator%3c=%3e,adjacent_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]")<Base> &&
|
||
[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[27](#range.adjacent.iterator-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13023)
|
||
|
||
*Returns*: x.*current_*.back() <=> y.*current_*.back()[.](#range.adjacent.iterator-27.sentence-1)
|
||
|
||
[ð](#lib:operator+,adjacent_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]")<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>;
|
||
`
|
||
|
||
[28](#range.adjacent.iterator-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13037)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r += n;return r;
|
||
|
||
[ð](#lib:operator-,adjacent_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]")<Base>;
|
||
`
|
||
|
||
[29](#range.adjacent.iterator-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13054)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r -= n;return r;
|
||
|
||
[ð](#lib:operator-,adjacent_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<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[30](#range.adjacent.iterator-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13071)
|
||
|
||
*Effects*: Equivalent to:return x.*current_*.back() - y.*current_*.back();
|
||
|
||
[ð](#lib:iter_move,adjacent_view::iterator)
|
||
|
||
`friend constexpr auto iter_move(const iterator& i) noexcept(see below);
|
||
`
|
||
|
||
[31](#range.adjacent.iterator-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13083)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*(ranges::iter_move, i.*current_*);
|
||
|
||
[32](#range.adjacent.iterator-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13088)
|
||
|
||
*Remarks*: The exception specification is equivalent to:noexcept(ranges::iter_move(declval<const iterator_t<*Base*>&>())) && is_nothrow_move_constructible_v<range_rvalue_reference_t<*Base*>>
|
||
|
||
[ð](#lib:iter_swap,adjacent_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[33](#range.adjacent.iterator-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13104)
|
||
|
||
*Preconditions*: None of the iterators in l.*current_* is equal to
|
||
an iterator in r.*current_*[.](#range.adjacent.iterator-33.sentence-1)
|
||
|
||
[34](#range.adjacent.iterator-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13109)
|
||
|
||
*Effects*: For every integer 0â¤i<N,
|
||
performsranges::iter_swap(l.*current_*[i], r.*current_*[i])[.](#range.adjacent.iterator-34.sentence-1)
|
||
|
||
[35](#range.adjacent.iterator-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13115)
|
||
|
||
*Remarks*: The exception specification is equivalent to:noexcept(ranges::iter_swap(declval<iterator_t<*Base*>>(), declval<iterator_t<*Base*>>()))
|
||
|
||
#### [25.7.27.4](#range.adjacent.sentinel) Class template adjacent_view::*sentinel* [[range.adjacent.sentinel]](range.adjacent.sentinel)
|
||
|
||
[ð](#lib:adjacent_view::sentinel)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && (N > 0)template<bool Const>class adjacent_view<V, N>::*sentinel* {using *Base* = *maybe-const*<Const, V>; // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only*constexpr explicit *sentinel*(sentinel_t<*Base*> end); // *exposition only*public:*sentinel*() = default; constexpr *sentinel*(*sentinel*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*maybe-const*<OtherConst, V>>>friend constexpr range_difference_t<*maybe-const*<OtherConst, V>>operator-(const *sentinel*& y, const *iterator*<OtherConst>& x); };}
|
||
|
||
[ð](#lib:adjacent_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<Base> end);
|
||
`
|
||
|
||
[1](#range.adjacent.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13164)
|
||
|
||
*Effects*: Initializes *end_* with end[.](#range.adjacent.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:adjacent_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[2](#range.adjacent.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13176)
|
||
|
||
*Effects*: Initializes *end_* with std::move(i.*end_*)[.](#range.adjacent.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,adjacent_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.adjacent.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13189)
|
||
|
||
*Effects*: Equivalent to: return x.*current_*.back() == y.*end_*;
|
||
|
||
[ð](#lib:operator-,adjacent_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[4](#range.adjacent.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13203)
|
||
|
||
*Effects*: Equivalent to: return x.*current_*.back() - y.*end_*;
|
||
|
||
[ð](#lib:operator-,adjacent_view::sentinel_)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, V>>
|
||
operator-(const sentinel& y, const iterator<OtherConst>& x);
|
||
`
|
||
|
||
[5](#range.adjacent.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13217)
|
||
|
||
*Effects*: Equivalent to: return y.*end_* - x.*current_*.back();
|
||
|
||
### [25.7.28](#range.adjacent.transform) Adjacent transform view [[range.adjacent.transform]](range.adjacent.transform)
|
||
|
||
#### [25.7.28.1](#range.adjacent.transform.overview) Overview [[range.adjacent.transform.overview]](range.adjacent.transform.overview)
|
||
|
||
[1](#range.adjacent.transform.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13226)
|
||
|
||
adjacent_transform_view takes an invocable object and
|
||
a view and produces a view
|
||
whose Mth element is the result of applying the invocable object
|
||
to the Mth through (M+Nâ1)th elements
|
||
of the original view[.](#range.adjacent.transform.overview-1.sentence-1)
|
||
|
||
If the original view has fewer than N elements, the resulting view is empty[.](#range.adjacent.transform.overview-1.sentence-2)
|
||
|
||
[2](#range.adjacent.transform.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13234)
|
||
|
||
The name views::adjacent_transform<N> denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.adjacent.transform.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F and
|
||
a constant expression N:
|
||
|
||
- [(2.1)](#range.adjacent.transform.overview-2.1)
|
||
|
||
If N is equal to 0 anddecltype((E)) models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),views::adjacent_transform<N>(E, F) is expression-equivalent to((void)E, views::zip_transform(F)),
|
||
except that the evaluations of E and F are
|
||
indeterminately sequenced[.](#range.adjacent.transform.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.adjacent.transform.overview-2.2)
|
||
|
||
Otherwise,
|
||
the expression views::adjacent_transform<N>(E, F) is
|
||
expression-equivalent toadjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F)[.](#range.adjacent.transform.overview-2.2.sentence-1)
|
||
|
||
[3](#range.adjacent.transform.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13255)
|
||
|
||
[*Example [1](#range.adjacent.transform.overview-example-1)*: vector v = {1, 2, 3, 4};
|
||
|
||
for (auto i : v | views::adjacent_transform<2>(std::multiplies())) { cout << i << ' '; // prints 2 6 12} â *end example*]
|
||
|
||
#### [25.7.28.2](#range.adjacent.transform.view) Class template adjacent_transform_view [[range.adjacent.transform.view]](range.adjacent.transform.view)
|
||
|
||
[ð](#lib:adjacent_transform_view)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && (N > 0) && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, *REPEAT*(range_reference_t<V>, N)...> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, *REPEAT*(range_reference_t<V>, N)...>>class adjacent_transform_view : public view_interface<adjacent_transform_view<V, F, N>> {*movable-box*<F> *fun_*; // *exposition only* adjacent_view<V, N> *inner_*; // *exposition only*using *InnerView* = adjacent_view<V, N>; // *exposition only*template<bool Const>using *inner-iterator* = iterator_t<*maybe-const*<Const, *InnerView*>>; // *exposition only*template<bool Const>using *inner-sentinel* = sentinel_t<*maybe-const*<Const, *InnerView*>>; // *exposition only*// [[range.adjacent.transform.iterator]](#range.adjacent.transform.iterator "25.7.28.3 Class template adjacent_transform_view::iterator"), class template adjacent_transform_view::*iterator*template<bool> class *iterator*; // *exposition only*// [[range.adjacent.transform.sentinel]](#range.adjacent.transform.sentinel "25.7.28.4 Class template adjacent_transform_view::sentinel"), class template adjacent_transform_view::*sentinel*template<bool> class *sentinel*; // *exposition only*public: adjacent_transform_view() = default; constexpr explicit adjacent_transform_view(V base, F fun); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *inner_*.base(); }constexpr V base() && { return std::move(*inner_*).base(); }constexpr auto begin() {return *iterator*<false>(*this, *inner_*.begin()); }constexpr auto begin() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const *InnerView*> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, *REPEAT*(range_reference_t<const V>, N)...> {return *iterator*<true>(*this, *inner_*.begin()); }constexpr auto end() {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<*InnerView*>) {return *iterator*<false>(*this, *inner_*.end()); } else {return *sentinel*<false>(*inner_*.end()); }}constexpr auto end() constrequires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const *InnerView*> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<const F&, *REPEAT*(range_reference_t<const V>, N)...> {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const *InnerView*>) {return *iterator*<true>(*this, *inner_*.end()); } else {return *sentinel*<true>(*inner_*.end()); }}constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<*InnerView*> {return *inner_*.size(); }constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const *InnerView*> {return *inner_*.size(); }constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<*InnerView*> {return *inner_*.reserve_hint(); }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]")<const *InnerView*> {return *inner_*.reserve_hint(); }};}
|
||
|
||
[ð](#lib:adjacent_transform_view,constructor)
|
||
|
||
`constexpr explicit adjacent_transform_view(V base, F fun);
|
||
`
|
||
|
||
[1](#range.adjacent.transform.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13356)
|
||
|
||
*Effects*: Initializes *fun_* with std::move(fun) and*inner_* with std::move(base)[.](#range.adjacent.transform.view-1.sentence-1)
|
||
|
||
#### [25.7.28.3](#range.adjacent.transform.iterator) Class template adjacent_transform_view::*iterator* [[range.adjacent.transform.iterator]](range.adjacent.transform.iterator)
|
||
|
||
[ð](#lib:adjacent_transform_view::iterator)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && (N > 0) && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, *REPEAT*(range_reference_t<V>, N)...> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, *REPEAT*(range_reference_t<V>, N)...>>template<bool Const>class adjacent_transform_view<V, F, N>::*iterator* {using *Parent* = *maybe-const*<Const, adjacent_transform_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only**Parent** *parent_* = nullptr; // *exposition only**inner-iterator*<Const> *inner_*; // *exposition only*constexpr *iterator*(*Parent*& parent, *inner-iterator*<Const> inner); // *exposition only*public:using iterator_category = *see below*; using iterator_concept = typename *inner-iterator*<Const>::iterator_concept; using value_type = remove_cvref_t<invoke_result_t<*maybe-const*<Const, F>&, *REPEAT*(range_reference_t<*Base*>, N)...>>; using difference_type = range_difference_t<*Base*>; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<*inner-iterator*<false>, *inner-iterator*<Const>>; constexpr decltype(auto) operator*() const noexcept(*see below*); 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 decltype(auto) 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, 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]")<*inner-iterator*<Const>>; 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]")<*inner-iterator*<Const>, *inner-iterator*<Const>>; };}
|
||
|
||
[1](#range.adjacent.transform.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13427)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") *iterator*::iterator_category is defined as follows:
|
||
|
||
- [(1.1)](#range.adjacent.transform.iterator-1.1)
|
||
|
||
If invoke_result_t<*maybe-const*<Const, F>&,*REPEAT*(range_reference_t<*Base*>, N)...> is not a reference,iterator_category denotes input_iterator_tag[.](#range.adjacent.transform.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.adjacent.transform.iterator-1.2)
|
||
|
||
Otherwise, let C denote the typeiterator_traits<iterator_t<*Base*>>::iterator_category[.](#range.adjacent.transform.iterator-1.2.sentence-1)
|
||
|
||
* [(1.2.1)](#range.adjacent.transform.iterator-1.2.1)
|
||
|
||
If [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<C, random_access_iterator_tag> is true,iterator_category denotes random_access_iterator_tag[.](#range.adjacent.transform.iterator-1.2.1.sentence-1)
|
||
|
||
* [(1.2.2)](#range.adjacent.transform.iterator-1.2.2)
|
||
|
||
Otherwise,
|
||
if [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<C, bidirectional_iterator_tag> is true,iterator_category denotes bidirectional_iterator_tag[.](#range.adjacent.transform.iterator-1.2.2.sentence-1)
|
||
|
||
* [(1.2.3)](#range.adjacent.transform.iterator-1.2.3)
|
||
|
||
Otherwise,
|
||
if [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<C, forward_iterator_tag> is true,iterator_category denotes forward_iterator_tag[.](#range.adjacent.transform.iterator-1.2.3.sentence-1)
|
||
|
||
* [(1.2.4)](#range.adjacent.transform.iterator-1.2.4)
|
||
|
||
Otherwise, iterator_category denotes input_iterator_tag[.](#range.adjacent.transform.iterator-1.2.4.sentence-1)
|
||
|
||
[ð](#lib:adjacent_transform_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent& parent, inner-iterator<Const> inner);
|
||
`
|
||
|
||
[2](#range.adjacent.transform.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13465)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent) and*inner_* with std::move(inner)[.](#range.adjacent.transform.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:adjacent_transform_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<inner-iterator<false>, inner-iterator<Const>>;
|
||
`
|
||
|
||
[3](#range.adjacent.transform.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13478)
|
||
|
||
*Effects*: Initializes *parent_* with i.*parent_* and*inner_* with std::move(i.*inner_*)[.](#range.adjacent.transform.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:operator*,adjacent_transform_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator*() const noexcept(see below);
|
||
`
|
||
|
||
[4](#range.adjacent.transform.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13490)
|
||
|
||
*Effects*: Equivalent to:return apply([&](const auto&... iters) -> decltype(auto) {return invoke(**parent_*->*fun_*, *iters...);}, *inner_*.*current_*);
|
||
|
||
[5](#range.adjacent.transform.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13499)
|
||
|
||
*Remarks*: Let Is be the pack 0, 1, …, (N - 1)[.](#range.adjacent.transform.iterator-5.sentence-1)
|
||
|
||
The exception specification is equivalent to:noexcept(invoke(**parent_*->*fun_*, *std::get<Is>(*inner_*.*current_*)...))
|
||
|
||
[ð](#lib:operator++,adjacent_transform_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[6](#range.adjacent.transform.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13514)
|
||
|
||
*Effects*: Equivalent to:++*inner_*;return *this;
|
||
|
||
[ð](#lib:operator++,adjacent_transform_view::iterator_)
|
||
|
||
`constexpr iterator operator++(int);
|
||
`
|
||
|
||
[7](#range.adjacent.transform.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13529)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,adjacent_transform_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[8](#range.adjacent.transform.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13545)
|
||
|
||
*Effects*: Equivalent to:--*inner_*;return *this;
|
||
|
||
[ð](#lib:operator--,adjacent_transform_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[9](#range.adjacent.transform.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13560)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,adjacent_transform_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]")<Base>;
|
||
`
|
||
|
||
[10](#range.adjacent.transform.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13576)
|
||
|
||
*Effects*: Equivalent to:*inner_* += x;return *this;
|
||
|
||
[ð](#lib:operator-=,adjacent_transform_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]")<Base>;
|
||
`
|
||
|
||
[11](#range.adjacent.transform.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13591)
|
||
|
||
*Effects*: Equivalent to:*inner_* -= x;return *this;
|
||
|
||
[ð](#lib:operator%5b%5d,adjacent_transform_view::iterator)
|
||
|
||
`constexpr decltype(auto) operator[](difference_type n) const
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[12](#range.adjacent.transform.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13607)
|
||
|
||
*Effects*: Equivalent to:return apply([&](const auto&... iters) -> decltype(auto) {return invoke(**parent_*->*fun_*, iters[n]...);}, *inner_*.*current_*);
|
||
|
||
[ð](#lib:operator==,adjacent_transform_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y);
|
||
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]")<inner-iterator<Const>>;
|
||
`
|
||
|
||
[13](#range.adjacent.transform.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13633)
|
||
|
||
Let *op* be the operator[.](#range.adjacent.transform.iterator-13.sentence-1)
|
||
|
||
[14](#range.adjacent.transform.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13636)
|
||
|
||
*Effects*: Equivalent to: return x.*inner_* *op* y.*inner_*;
|
||
|
||
[ð](#lib:operator+,adjacent_transform_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]")<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>;
|
||
`
|
||
|
||
[15](#range.adjacent.transform.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13650)
|
||
|
||
*Effects*: Equivalent to: return *iterator*(*i.*parent_*, i.*inner_* + n);
|
||
|
||
[ð](#lib:operator-,adjacent_transform_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]")<Base>;
|
||
`
|
||
|
||
[16](#range.adjacent.transform.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13662)
|
||
|
||
*Effects*: Equivalent to: return *iterator*(*i.*parent_*, i.*inner_* - n);
|
||
|
||
[ð](#lib:operator-,adjacent_transform_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]")<inner-iterator<Const>, inner-iterator<Const>>;
|
||
`
|
||
|
||
[17](#range.adjacent.transform.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13674)
|
||
|
||
*Effects*: Equivalent to: return x.*inner_* - y.*inner_*;
|
||
|
||
#### [25.7.28.4](#range.adjacent.transform.sentinel) Class template adjacent_transform_view::*sentinel* [[range.adjacent.transform.sentinel]](range.adjacent.transform.sentinel)
|
||
|
||
[ð](#lib:adjacent_transform_view::sentinel)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]") F, size_t N>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && (N > 0) && is_object_v<F> &&[regular_invocable](concept.regularinvocable#concept:regular_invocable "18.7.3 Concept regular_invocable [concept.regularinvocable]")<F&, *REPEAT*(range_reference_t<V>, N)...> &&[*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]")<invoke_result_t<F&, *REPEAT*(range_reference_t<V>, N)...>>template<bool Const>class adjacent_transform_view<V, F, N>::*sentinel* {*inner-sentinel*<Const> *inner_*; // *exposition only*constexpr explicit *sentinel*(*inner-sentinel*<Const> inner); // *exposition only*public:*sentinel*() = default; constexpr *sentinel*(*sentinel*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<*inner-sentinel*<false>, *inner-sentinel*<Const>>; template<bool OtherConst>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<*inner-sentinel*<Const>, *inner-iterator*<OtherConst>>friend constexpr bool operator==(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<*inner-sentinel*<Const>, *inner-iterator*<OtherConst>>friend constexpr range_difference_t<*maybe-const*<OtherConst, *InnerView*>>operator-(const *iterator*<OtherConst>& x, const *sentinel*& y); template<bool OtherConst>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<*inner-sentinel*<Const>, *inner-iterator*<OtherConst>>friend constexpr range_difference_t<*maybe-const*<OtherConst, *InnerView*>>operator-(const *sentinel*& x, const *iterator*<OtherConst>& y); };}
|
||
|
||
[ð](#lib:adjacent_transform_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(inner-sentinel<Const> inner);
|
||
`
|
||
|
||
[1](#range.adjacent.transform.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13721)
|
||
|
||
*Effects*: Initializes *inner_* with inner[.](#range.adjacent.transform.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:adjacent_transform_view::sentinel,constructor_)
|
||
|
||
`constexpr sentinel(sentinel<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<inner-sentinel<false>, inner-sentinel<Const>>;
|
||
`
|
||
|
||
[2](#range.adjacent.transform.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13733)
|
||
|
||
*Effects*: Initializes *inner_* with std::move(i.*inner_*)[.](#range.adjacent.transform.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,adjacent_transform_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
||
friend constexpr bool operator==(const iterator<OtherConst>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.adjacent.transform.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13746)
|
||
|
||
*Effects*: Equivalent to: return x.*inner_* == y.*inner_*;
|
||
|
||
[ð](#lib:operator-,adjacent_transform_view::sentinel)
|
||
|
||
`template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
||
operator-(const iterator<OtherConst>& x, const sentinel& y);
|
||
|
||
template<bool OtherConst>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<inner-sentinel<Const>, inner-iterator<OtherConst>>
|
||
friend constexpr range_difference_t<maybe-const<OtherConst, InnerView>>
|
||
operator-(const sentinel& x, const iterator<OtherConst>& y);
|
||
`
|
||
|
||
[4](#range.adjacent.transform.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13765)
|
||
|
||
*Effects*: Equivalent to: return x.*inner_* - y.*inner_*;
|
||
|
||
### [25.7.29](#range.chunk) Chunk view [[range.chunk]](range.chunk)
|
||
|
||
#### [25.7.29.1](#range.chunk.overview) Overview [[range.chunk.overview]](range.chunk.overview)
|
||
|
||
[1](#range.chunk.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[.](#range.chunk.overview-1.sentence-1)
|
||
|
||
The last view in the range can have fewer than N elements[.](#range.chunk.overview-1.sentence-2)
|
||
|
||
[2](#range.chunk.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"))[.](#range.chunk.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and N,
|
||
the expression views::chunk(E, N) is expression-equivalent tochunk_view(E, N)[.](#range.chunk.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.chunk.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](#range.chunk.view.input) Class template chunk_view for input ranges [[range.chunk.view.input]](range.chunk.view.input)
|
||
|
||
[ð](#lib:chunk_view)
|
||
|
||
namespace std::ranges {template<class I>constexpr 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]")<V>class chunk_view : public view_interface<chunk_view<V>> { V *base_*; // *exposition only* range_difference_t<V> *n_*; // *exposition only* range_difference_t<V> *remainder_* = 0; // *exposition only**non-propagating-cache*<iterator_t<V>> *current_*; // *exposition only*// [[range.chunk.outer.iter]](#range.chunk.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]](#range.chunk.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<V> n); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { 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]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; 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]")<const V>; }; template<class R> chunk_view(R&&, range_difference_t<R>) -> chunk_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:chunk_view,constructor)
|
||
|
||
`constexpr explicit chunk_view(V base, range_difference_t<V> n);
|
||
`
|
||
|
||
[1](#range.chunk.view.input-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13861)
|
||
|
||
*Preconditions*: n > 0 is true[.](#range.chunk.view.input-1.sentence-1)
|
||
|
||
[2](#range.chunk.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[.](#range.chunk.view.input-2.sentence-1)
|
||
|
||
[ð](#lib:begin,chunk_view)
|
||
|
||
`constexpr outer-iterator begin();
|
||
`
|
||
|
||
[3](#range.chunk.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](#range.chunk.view.input-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13893)
|
||
|
||
*Returns*: default_sentinel[.](#range.chunk.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]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[5](#range.chunk.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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[6](#range.chunk.view.input-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13920)
|
||
|
||
*Effects*: Equivalent to:auto s = static_cast<range_difference_t<decltype((*base_*))>>(ranges::reserve_hint(*base_*));return *to-unsigned-like*(*div-ceil*(s, *n_*));
|
||
|
||
#### [25.7.29.3](#range.chunk.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]")<V>class chunk_view<V>::*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<V>; // [[range.chunk.outer.value]](#range.chunk.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]")<sentinel_t<V>, iterator_t<V>>; 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]")<sentinel_t<V>, iterator_t<V>>; };}
|
||
|
||
[ð](#lib:chunk_view::outer-iterator,constructor)
|
||
|
||
`constexpr explicit outer-iterator(chunk_view& parent);
|
||
`
|
||
|
||
[1](#range.chunk.outer.iter-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13971)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent)[.](#range.chunk.outer.iter-1.sentence-1)
|
||
|
||
[ð](#lib:operator*,chunk_view::outer-iterator)
|
||
|
||
`constexpr value_type operator*() const;
|
||
`
|
||
|
||
[2](#range.chunk.outer.iter-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13982)
|
||
|
||
*Preconditions*: *this == default_sentinel is false[.](#range.chunk.outer.iter-2.sentence-1)
|
||
|
||
[3](#range.chunk.outer.iter-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13986)
|
||
|
||
*Returns*: value_type(**parent_*)[.](#range.chunk.outer.iter-3.sentence-1)
|
||
|
||
[ð](#lib:operator++,chunk_view::outer-iterator)
|
||
|
||
`constexpr outer-iterator& operator++();
|
||
`
|
||
|
||
[4](#range.chunk.outer.iter-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L13997)
|
||
|
||
*Preconditions*: *this == default_sentinel is false[.](#range.chunk.outer.iter-4.sentence-1)
|
||
|
||
[5](#range.chunk.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](#range.chunk.outer.iter-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14017)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.chunk.outer.iter-6.sentence-1)
|
||
|
||
[ð](#lib:operator==,chunk_view::outer-iterator)
|
||
|
||
`friend constexpr bool operator==(const outer-iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[7](#range.chunk.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]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[8](#range.chunk.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]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[9](#range.chunk.outer.iter-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14062)
|
||
|
||
*Effects*: Equivalent to: return -(y - x);
|
||
|
||
#### [25.7.29.4](#range.chunk.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]")<V>struct chunk_view<V>::*outer-iterator*::value_type : view_interface<value_type> {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]")<sentinel_t<V>, iterator_t<V>>; constexpr auto reserve_hint() const noexcept; };}
|
||
|
||
[ð](#lib:chunk_view::outer-iterator::value_type,constructor)
|
||
|
||
`constexpr explicit value_type(chunk_view& parent);
|
||
`
|
||
|
||
[1](#range.chunk.outer.value-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14098)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent)[.](#range.chunk.outer.value-1.sentence-1)
|
||
|
||
[ð](#lib:begin,chunk_view::outer-iterator::value_type)
|
||
|
||
`constexpr inner-iterator begin() const noexcept;
|
||
`
|
||
|
||
[2](#range.chunk.outer.value-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14109)
|
||
|
||
*Returns*: *inner-iterator*(**parent_*)[.](#range.chunk.outer.value-2.sentence-1)
|
||
|
||
[ð](#lib:end,chunk_view::outer-iterator::value_type)
|
||
|
||
`constexpr default_sentinel_t end() const noexcept;
|
||
`
|
||
|
||
[3](#range.chunk.outer.value-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14120)
|
||
|
||
*Returns*: default_sentinel[.](#range.chunk.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]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[4](#range.chunk.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](#range.chunk.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](#range.chunk.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]")<V>class chunk_view<V>::*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<V>; using value_type = range_value_t<V>; *inner-iterator*(*inner-iterator*&&) = default; *inner-iterator*& operator=(*inner-iterator*&&) = default; constexpr const iterator_t<V>& base() const &; constexpr range_reference_t<V> 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]")<sentinel_t<V>, iterator_t<V>>; 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]")<sentinel_t<V>, iterator_t<V>>; friend constexpr range_rvalue_reference_t<V> 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]")<iterator_t<V>>; };}
|
||
|
||
[ð](#lib:chunk_view::inner-iterator,constructor)
|
||
|
||
`constexpr explicit inner-iterator(chunk_view& parent) noexcept;
|
||
`
|
||
|
||
[1](#range.chunk.inner.iter-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14204)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent)[.](#range.chunk.inner.iter-1.sentence-1)
|
||
|
||
[ð](#lib:base,chunk_view::inner-iterator)
|
||
|
||
`constexpr const iterator_t<V>& base() const &;
|
||
`
|
||
|
||
[2](#range.chunk.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<V> operator*() const;
|
||
`
|
||
|
||
[3](#range.chunk.inner.iter-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14226)
|
||
|
||
*Preconditions*: *this == default_sentinel is false[.](#range.chunk.inner.iter-3.sentence-1)
|
||
|
||
[4](#range.chunk.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](#range.chunk.inner.iter-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14241)
|
||
|
||
*Preconditions*: *this == default_sentinel is false[.](#range.chunk.inner.iter-5.sentence-1)
|
||
|
||
[6](#range.chunk.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](#range.chunk.inner.iter-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14264)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.chunk.inner.iter-7.sentence-1)
|
||
|
||
[ð](#lib:operator==,chunk_view::inner-iterator)
|
||
|
||
`friend constexpr bool operator==(const inner-iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[8](#range.chunk.inner.iter-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14275)
|
||
|
||
*Returns*: x.*parent_*->*remainder_* == 0[.](#range.chunk.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]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[9](#range.chunk.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]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[10](#range.chunk.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<V> iter_move(const inner-iterator& i)
|
||
noexcept(noexcept(ranges::iter_move(*i.parent_->current_)));
|
||
`
|
||
|
||
[11](#range.chunk.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]")<iterator_t<V>>;
|
||
`
|
||
|
||
[12](#range.chunk.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](#range.chunk.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]")<V>class chunk_view<V> : public view_interface<chunk_view<V>> { V *base_*; // *exposition only* range_difference_t<V> *n_*; // *exposition only*// [[range.chunk.fwd.iter]](#range.chunk.fwd.iter "25.7.29.7 Class template chunk_view::iterator for forward ranges"), class template chunk_view::*iterator*template<bool> class *iterator*; // *exposition only*public:constexpr explicit chunk_view(V base, range_difference_t<V> n); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>) {return *iterator*<false>(this, ranges::begin(*base_*)); }constexpr auto begin() const requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V> {return *iterator*<true>(this, ranges::begin(*base_*)); }constexpr auto end() requires (<V>) {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>) {auto missing = (*n_* - ranges::distance(*base_*) % *n_*) % *n_*; return *iterator*<false>(this, ranges::end(*base_*), missing); } else if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && <V>) {return *iterator*<false>(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]")<const V> {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>) {auto missing = (*n_* - ranges::distance(*base_*) % *n_*) % *n_*; return *iterator*<true>(this, ranges::end(*base_*), missing); } else if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && <const V>) {return *iterator*<true>(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]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; 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]")<const V>; };}
|
||
|
||
[ð](#lib:chunk_view,constructor_)
|
||
|
||
`constexpr explicit chunk_view(V base, range_difference_t<V> n);
|
||
`
|
||
|
||
[1](#range.chunk.view.fwd-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14400)
|
||
|
||
*Preconditions*: n > 0 is true[.](#range.chunk.view.fwd-1.sentence-1)
|
||
|
||
[2](#range.chunk.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[.](#range.chunk.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]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[3](#range.chunk.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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[4](#range.chunk.view.fwd-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14432)
|
||
|
||
*Effects*: Equivalent to:auto s = static_cast<range_difference_t<decltype((*base_*))>>(ranges::reserve_hint(*base_*));return *to-unsigned-like*(*div-ceil*(s, *n_*));
|
||
|
||
#### [25.7.29.7](#range.chunk.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]")<V>template<bool Const>class chunk_view<V>::*iterator* {using *Parent* = *maybe-const*<Const, chunk_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *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*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>&& [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, 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]")<iterator_t<*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 *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*>, 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]")<sentinel_t<*Base*>, 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]")<sentinel_t<*Base*>, iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.chunk.fwd.iter-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14521)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.chunk.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[.](#range.chunk.fwd.iter-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.chunk.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[.](#range.chunk.fwd.iter-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.chunk.fwd.iter-1.3)
|
||
|
||
Otherwise, iterator_concept denotes forward_iterator_tag[.](#range.chunk.fwd.iter-1.3.sentence-1)
|
||
|
||
[ð](#lib:chunk_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent* parent, iterator_t<Base> current,
|
||
range_difference_t<Base> missing = 0);
|
||
`
|
||
|
||
[2](#range.chunk.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[.](#range.chunk.fwd.iter-2.sentence-1)
|
||
|
||
[ð](#lib:chunk_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>
|
||
&& [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[3](#range.chunk.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_*[.](#range.chunk.fwd.iter-3.sentence-1)
|
||
|
||
[ð](#lib:base,chunk_view::iterator)
|
||
|
||
`constexpr iterator_t<Base> base() const;
|
||
`
|
||
|
||
[4](#range.chunk.fwd.iter-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14571)
|
||
|
||
*Returns*: *current_*[.](#range.chunk.fwd.iter-4.sentence-1)
|
||
|
||
[ð](#lib:operator*,chunk_view::iterator)
|
||
|
||
`constexpr value_type operator*() const;
|
||
`
|
||
|
||
[5](#range.chunk.fwd.iter-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14582)
|
||
|
||
*Preconditions*: *current_* != *end_* is true[.](#range.chunk.fwd.iter-5.sentence-1)
|
||
|
||
[6](#range.chunk.fwd.iter-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14586)
|
||
|
||
*Returns*: views::take(subrange(*current_*, *end_*), *n_*)[.](#range.chunk.fwd.iter-6.sentence-1)
|
||
|
||
[ð](#lib:operator++,chunk_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.chunk.fwd.iter-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14597)
|
||
|
||
*Preconditions*: *current_* != *end_* is true[.](#range.chunk.fwd.iter-7.sentence-1)
|
||
|
||
[8](#range.chunk.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](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[10](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[11](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[12](#range.chunk.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[.](#range.chunk.fwd.iter-12.sentence-1)
|
||
|
||
[*Note [1](#range.chunk.fwd.iter-note-1)*:
|
||
|
||
If x is negative, the *Effects* paragraph implies a precondition[.](#range.chunk.fwd.iter-12.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[13](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[14](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[15](#range.chunk.fwd.iter-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14708)
|
||
|
||
*Returns*: *(*this + n)[.](#range.chunk.fwd.iter-15.sentence-1)
|
||
|
||
[ð](#lib:operator-=,chunk_view::iterator_)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y);
|
||
`
|
||
|
||
[16](#range.chunk.fwd.iter-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14719)
|
||
|
||
*Returns*: x.*current_* == y.*current_*[.](#range.chunk.fwd.iter-16.sentence-1)
|
||
|
||
[ð](#lib:operator==,chunk_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[17](#range.chunk.fwd.iter-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14730)
|
||
|
||
*Returns*: x.*current_* == x.*end_*[.](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[18](#range.chunk.fwd.iter-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14742)
|
||
|
||
*Returns*: x.*current_* < y.*current_*[.](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[19](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[20](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[21](#range.chunk.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]")<Base> &&
|
||
[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[22](#range.chunk.fwd.iter-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14791)
|
||
|
||
*Returns*: x.*current_* <=> y.*current_*[.](#range.chunk.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]")<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>;
|
||
`
|
||
|
||
[23](#range.chunk.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]")<Base>;
|
||
`
|
||
|
||
[24](#range.chunk.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<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[25](#range.chunk.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_*[.](#range.chunk.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]")<sentinel_t<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[26](#range.chunk.fwd.iter-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14851)
|
||
|
||
*Returns*: *div-ceil*(x.*end_* - x.*current_*, x.*n_*)[.](#range.chunk.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]")<sentinel_t<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[27](#range.chunk.fwd.iter-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14863)
|
||
|
||
*Effects*: Equivalent to: return -(y - x);
|
||
|
||
### [25.7.30](#range.slide) Slide view [[range.slide]](range.slide)
|
||
|
||
#### [25.7.30.1](#range.slide.overview) Overview [[range.slide.overview]](range.slide.overview)
|
||
|
||
[1](#range.slide.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14872)
|
||
|
||
slide_view takes a view and a number N and
|
||
produces a view
|
||
whose Mth element is a view over
|
||
the Mth through(M+Nâ1)th elements
|
||
of the original view[.](#range.slide.overview-1.sentence-1)
|
||
|
||
If the original view has fewer than N elements,
|
||
the resulting view is empty[.](#range.slide.overview-1.sentence-2)
|
||
|
||
[2](#range.slide.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14882)
|
||
|
||
The name views::slide denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.slide.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and N,
|
||
the expression views::slide(E, N) is expression-equivalent toslide_view(E, N)[.](#range.slide.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.slide.overview-example-1)*: vector v = {1, 2, 3, 4};
|
||
|
||
for (auto i : v | views::slide(2)) { cout << '[' << i[0] << ", " << i[1] << "] "; // prints [1, 2] [2, 3] [3, 4]} â *end example*]
|
||
|
||
#### [25.7.30.2](#range.slide.view) Class template slide_view [[range.slide.view]](range.slide.view)
|
||
|
||
[ð](#lib:slide_view)
|
||
|
||
namespace std::ranges {template<class V>concept [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]") = [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>; // *exposition only*template<class V>concept [*slide-caches-last*](#concept:slide-caches-last "25.7.30.2 Class template slide_view [range.slide.view]") = // *exposition only*<V> && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V> && [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>; template<class V>concept [*slide-caches-first*](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]") = // *exposition only*<V> && <V>; template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class slide_view : public view_interface<slide_view<V>> { V *base_*; // *exposition only* range_difference_t<V> *n_*; // *exposition only*// [[range.slide.iterator]](#range.slide.iterator "25.7.30.3 Class template slide_view::iterator"), class template slide_view::*iterator*template<bool> class *iterator*; // *exposition only*// [[range.slide.sentinel]](#range.slide.sentinel "25.7.30.4 Class slide_view::sentinel"), class slide_view::*sentinel*class *sentinel*; // *exposition only*public:constexpr explicit slide_view(V base, range_difference_t<V> n); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { 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]")<V> && [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>)); constexpr auto begin() const requires [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>; constexpr auto end()requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>)); constexpr auto end() const requires [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>; constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hintsize() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; constexpr auto reserve_hintsize() const requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<const V>; }; template<class R> slide_view(R&&, range_difference_t<R>) -> slide_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:slide_view,constructor_)
|
||
|
||
`constexpr explicit slide_view(V base, range_difference_t<V> n);
|
||
`
|
||
|
||
[1](#range.slide.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14960)
|
||
|
||
*Preconditions*: n > 0 is true[.](#range.slide.view-1.sentence-1)
|
||
|
||
[2](#range.slide.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14964)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*n_* with n[.](#range.slide.view-2.sentence-1)
|
||
|
||
[ð](#lib:begin,slide_view)
|
||
|
||
`constexpr auto begin()
|
||
requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [slide-caches-nothing](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>));
|
||
`
|
||
|
||
[3](#range.slide.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14977)
|
||
|
||
*Returns*:
|
||
|
||
- [(3.1)](#range.slide.view-3.1)
|
||
|
||
If V models [*slide-caches-first*](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]"),*iterator*<false>(ranges::begin(*base_*),
|
||
ranges::next(ranges::begin(*base_*), *n_* - 1, ranges::end(*base_*)), *n_*)
|
||
|
||
- [(3.2)](#range.slide.view-3.2)
|
||
|
||
Otherwise, *iterator*<false>(ranges::begin(*base_*), *n_*)[.](#range.slide.view-3.sentence-1)
|
||
|
||
[4](#range.slide.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L14990)
|
||
|
||
*Remarks*: In order to provide the amortized constant-time complexity
|
||
required by the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept,
|
||
this function caches the result within the slide_view for use on subsequent calls
|
||
when V models [*slide-caches-first*](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]")[.](#range.slide.view-4.sentence-1)
|
||
|
||
[ð](#lib:begin,slide_view_)
|
||
|
||
`constexpr auto begin() const requires [slide-caches-nothing](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>;
|
||
`
|
||
|
||
[5](#range.slide.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15005)
|
||
|
||
*Returns*: *iterator*<true>(ranges::begin(*base_*), *n_*)[.](#range.slide.view-5.sentence-1)
|
||
|
||
[ð](#lib:end,slide_view)
|
||
|
||
`constexpr auto end()
|
||
requires (!([simple-view](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<V> && [slide-caches-nothing](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>));
|
||
`
|
||
|
||
[6](#range.slide.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15017)
|
||
|
||
*Returns*:
|
||
|
||
- [(6.1)](#range.slide.view-6.1)
|
||
|
||
If V models [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]"),*iterator*<false>(ranges::begin(*base_*) + range_difference_t<V>(size()), *n_*)
|
||
|
||
- [(6.2)](#range.slide.view-6.2)
|
||
|
||
Otherwise, if V models [*slide-caches-last*](#concept:slide-caches-last "25.7.30.2 Class template slide_view [range.slide.view]"),*iterator*<false>(ranges::prev(ranges::end(*base_*), *n_* - 1, ranges::begin(*base_*)), *n_*)
|
||
|
||
- [(6.3)](#range.slide.view-6.3)
|
||
|
||
Otherwise, if V models [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"),*iterator*<false>(ranges::end(*base_*), ranges::end(*base_*), *n_*)
|
||
|
||
- [(6.4)](#range.slide.view-6.4)
|
||
|
||
Otherwise, *sentinel*(ranges::end(*base_*))[.](#range.slide.view-6.sentence-1)
|
||
|
||
[7](#range.slide.view-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15039)
|
||
|
||
*Remarks*: In order to provide the amortized constant-time complexity
|
||
required by the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept,
|
||
this function caches the result within the slide_view for use on subsequent calls
|
||
when V models [*slide-caches-last*](#concept:slide-caches-last "25.7.30.2 Class template slide_view [range.slide.view]")[.](#range.slide.view-7.sentence-1)
|
||
|
||
[ð](#lib:end,slide_view_)
|
||
|
||
`constexpr auto end() const requires [slide-caches-nothing](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]")<const V>;
|
||
`
|
||
|
||
[8](#range.slide.view-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15054)
|
||
|
||
*Returns*: begin() + range_difference_t<const V>(size())[.](#range.slide.view-8.sentence-1)
|
||
|
||
[ð](#lib:size,slide_view)
|
||
|
||
`constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[9](#range.slide.view-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15066)
|
||
|
||
*Effects*: Equivalent to:auto sz = ranges::distance(*base_*) - *n_* + 1;if (sz < 0) sz = 0;return *to-unsigned-like*(sz);
|
||
|
||
[ð](#lib:reserve_hint,slide_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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[10](#range.slide.view-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15083)
|
||
|
||
*Effects*: Equivalent to:auto sz = static_cast<range_difference_t<decltype((*base_*))>>(ranges::reserve_hint(*base_*)) -*n_* + 1;if (sz < 0) sz = 0;return *to-unsigned-like*(sz);
|
||
|
||
#### [25.7.30.3](#range.slide.iterator) Class template slide_view::*iterator* [[range.slide.iterator]](range.slide.iterator)
|
||
|
||
[ð](#lib:slide_view::iterator)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>template<bool Const>class slide_view<V>::*iterator* {using *Base* = *maybe-const*<Const, V>; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only* iterator_t<*Base*> *last_ele_* = iterator_t<*Base*>(); // *exposition only*,// present only if *Base* models [*slide-caches-first*](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]") range_difference_t<*Base*> *n_* = 0; // *exposition only*constexpr *iterator*(iterator_t<*Base*> current, range_difference_t<*Base*> n) // *exposition only*requires (<*Base*>); constexpr *iterator*(iterator_t<*Base*> current, iterator_t<*Base*> last_ele, // *exposition only* range_difference_t<*Base*> n)requires [*slide-caches-first*](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]")<*Base*>; public:using iterator_category = input_iterator_tag; using iterator_concept = *see below*; using value_type = decltype(views::counted(*current_*, *n_*)); using difference_type = range_difference_t<*Base*>; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr auto 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 auto 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, 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]")<iterator_t<*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 *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*>, iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.slide.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15167)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.slide.iterator-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[.](#range.slide.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.slide.iterator-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[.](#range.slide.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.slide.iterator-1.3)
|
||
|
||
Otherwise, iterator_concept denotes forward_iterator_tag[.](#range.slide.iterator-1.3.sentence-1)
|
||
|
||
[2](#range.slide.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15180)
|
||
|
||
If the invocation of any non-const member function of *iterator* exits via an exception, the *iterator* acquires a singular value[.](#range.slide.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:slide_view::iterator,constructor)
|
||
|
||
`constexpr iterator(iterator_t<Base> current, range_difference_t<Base> n)
|
||
requires (<Base>);
|
||
`
|
||
|
||
[3](#range.slide.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15191)
|
||
|
||
*Effects*: Initializes *current_* with current and*n_* with n[.](#range.slide.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:slide_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator_t<Base> current, iterator_t<Base> last_ele,
|
||
range_difference_t<Base> n)
|
||
requires [slide-caches-first](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]")<Base>;
|
||
`
|
||
|
||
[4](#range.slide.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15205)
|
||
|
||
*Effects*: Initializes *current_* with current,*last_ele_* with last_ele, and*n_* with n[.](#range.slide.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:slide_view::iterator,constructor__)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[5](#range.slide.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15219)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*) and*n_* with i.*n_*[.](#range.slide.iterator-5.sentence-1)
|
||
|
||
[*Note [1](#range.slide.iterator-note-1)*:
|
||
|
||
*iterator*<true> can only be formed
|
||
when *Base* models [*slide-caches-nothing*](#concept:slide-caches-nothing "25.7.30.2 Class template slide_view [range.slide.view]"),
|
||
in which case *last_ele_* is not present[.](#range.slide.iterator-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator*,slide_view::iterator)
|
||
|
||
`constexpr auto operator*() const;
|
||
`
|
||
|
||
[6](#range.slide.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15236)
|
||
|
||
*Returns*: views::counted(*current_*, *n_*)[.](#range.slide.iterator-6.sentence-1)
|
||
|
||
[ð](#lib:operator++,slide_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.slide.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15247)
|
||
|
||
*Preconditions*: *current_* and *last_ele_* (if present) are incrementable[.](#range.slide.iterator-7.sentence-1)
|
||
|
||
[8](#range.slide.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15251)
|
||
|
||
*Postconditions*: *current_* and *last_ele_* (if present) are
|
||
each equal to ranges::next(i),
|
||
where i is the value of that data member before the call[.](#range.slide.iterator-8.sentence-1)
|
||
|
||
[9](#range.slide.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15257)
|
||
|
||
*Returns*: *this[.](#range.slide.iterator-9.sentence-1)
|
||
|
||
[ð](#lib:operator++,slide_view::iterator_)
|
||
|
||
`constexpr iterator operator++(int);
|
||
`
|
||
|
||
[10](#range.slide.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15268)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,slide_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[11](#range.slide.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15284)
|
||
|
||
*Preconditions*: *current_* and *last_ele_* (if present) are decrementable[.](#range.slide.iterator-11.sentence-1)
|
||
|
||
[12](#range.slide.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15288)
|
||
|
||
*Postconditions*: *current_* and *last_ele_* (if present) are
|
||
each equal to ranges::prev(i),
|
||
where i is the value of that data member before the call[.](#range.slide.iterator-12.sentence-1)
|
||
|
||
[13](#range.slide.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15294)
|
||
|
||
*Returns*: *this[.](#range.slide.iterator-13.sentence-1)
|
||
|
||
[ð](#lib:operator--,slide_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[14](#range.slide.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15305)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,slide_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]")<Base>;
|
||
`
|
||
|
||
[15](#range.slide.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15322)
|
||
|
||
*Preconditions*: *current_* + x and *last_ele_* + x (if *last_ele_* is present)
|
||
have well-defined behavior[.](#range.slide.iterator-15.sentence-1)
|
||
|
||
[16](#range.slide.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15327)
|
||
|
||
*Postconditions*: *current_* and *last_ele_* (if present) are
|
||
each equal to i + x,
|
||
where i is the value of that data member before the call[.](#range.slide.iterator-16.sentence-1)
|
||
|
||
[17](#range.slide.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15333)
|
||
|
||
*Returns*: *this[.](#range.slide.iterator-17.sentence-1)
|
||
|
||
[ð](#lib:operator-=,slide_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]")<Base>;
|
||
`
|
||
|
||
[18](#range.slide.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15345)
|
||
|
||
*Preconditions*: *current_* - x and *last_ele_* - x (if *last_ele_* is present)
|
||
have well-defined behavior[.](#range.slide.iterator-18.sentence-1)
|
||
|
||
[19](#range.slide.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15350)
|
||
|
||
*Postconditions*: *current_* and *last_ele_* (if present) are
|
||
each equal to i - x,
|
||
where i is the value of that data member before the call[.](#range.slide.iterator-19.sentence-1)
|
||
|
||
[20](#range.slide.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15356)
|
||
|
||
*Returns*: *this[.](#range.slide.iterator-20.sentence-1)
|
||
|
||
[ð](#lib:operator%5b%5d,slide_view::iterator)
|
||
|
||
`constexpr auto operator[](difference_type n) const
|
||
requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[21](#range.slide.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15368)
|
||
|
||
*Effects*: Equivalent to: return views::counted(*current_* + n, *n_*);
|
||
|
||
[ð](#lib:operator==,slide_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y);
|
||
`
|
||
|
||
[22](#range.slide.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15379)
|
||
|
||
*Returns*: If *last_ele_* is present,x.*last_ele_* == y.*last_ele_*;
|
||
otherwise, x.*current_* == y.*current_*[.](#range.slide.iterator-22.sentence-1)
|
||
|
||
[ð](#lib:operator%3c,slide_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]")<Base>;
|
||
`
|
||
|
||
[23](#range.slide.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15393)
|
||
|
||
*Returns*: x.*current_* < y.*current_*[.](#range.slide.iterator-23.sentence-1)
|
||
|
||
[ð](#lib:operator%3e,slide_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]")<Base>;
|
||
`
|
||
|
||
[24](#range.slide.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15405)
|
||
|
||
*Effects*: Equivalent to: return y < x;
|
||
|
||
[ð](#lib:operator%3c=,slide_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]")<Base>;
|
||
`
|
||
|
||
[25](#range.slide.iterator-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15417)
|
||
|
||
*Effects*: Equivalent to: return !(y < x);
|
||
|
||
[ð](#lib:operator%3e=,slide_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]")<Base>;
|
||
`
|
||
|
||
[26](#range.slide.iterator-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15429)
|
||
|
||
*Effects*: Equivalent to: return !(x < y);
|
||
|
||
[ð](#lib:operator%3c=%3e,slide_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]")<Base> &&
|
||
[three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[27](#range.slide.iterator-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15442)
|
||
|
||
*Returns*: x.*current_* <=> y.*current_*[.](#range.slide.iterator-27.sentence-1)
|
||
|
||
[ð](#lib:operator+,slide_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]")<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>;
|
||
`
|
||
|
||
[28](#range.slide.iterator-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15456)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r += n;return r;
|
||
|
||
[ð](#lib:operator-,slide_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]")<Base>;
|
||
`
|
||
|
||
[29](#range.slide.iterator-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15473)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r -= n;return r;
|
||
|
||
[ð](#lib:operator-,slide_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<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[30](#range.slide.iterator-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15490)
|
||
|
||
*Returns*: If *last_ele_* is present,x.*last_ele_* - y.*last_ele_*;
|
||
otherwise, x.*current_* - y.*current_*[.](#range.slide.iterator-30.sentence-1)
|
||
|
||
#### [25.7.30.4](#range.slide.sentinel) Class slide_view::*sentinel* [[range.slide.sentinel]](range.slide.sentinel)
|
||
|
||
[ð](#lib:slide_view::sentinel)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class slide_view<V>::*sentinel* { sentinel_t<V> *end_* = sentinel_t<V>(); // *exposition only*constexpr explicit *sentinel*(sentinel_t<V> end); // *exposition only*public:*sentinel*() = default; friend constexpr bool operator==(const *iterator*<false>& x, const *sentinel*& y); friend constexpr range_difference_t<V>operator-(const *iterator*<false>& x, const *sentinel*& y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>; friend constexpr range_difference_t<V>operator-(const *sentinel*& y, const *iterator*<false>& x)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>; };}
|
||
|
||
[1](#range.slide.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15524)
|
||
|
||
[*Note [1](#range.slide.sentinel-note-1)*:
|
||
|
||
*sentinel* is used
|
||
only when [*slide-caches-first*](#concept:slide-caches-first "25.7.30.2 Class template slide_view [range.slide.view]")<V> is true[.](#range.slide.sentinel-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:slide_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(sentinel_t<V> end);
|
||
`
|
||
|
||
[2](#range.slide.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15536)
|
||
|
||
*Effects*: Initializes *end_* with end[.](#range.slide.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,slide_view::sentinel)
|
||
|
||
`friend constexpr bool operator==(const iterator<false>& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.slide.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15547)
|
||
|
||
*Returns*: x.*last_ele_* == y.*end_*[.](#range.slide.sentinel-3.sentence-1)
|
||
|
||
[ð](#lib:operator-,slide_view::sentinel)
|
||
|
||
`friend constexpr range_difference_t<V>
|
||
operator-(const iterator<false>& x, const sentinel& y)
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[4](#range.slide.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15560)
|
||
|
||
*Returns*: x.*last_ele_* - y.*end_*[.](#range.slide.sentinel-4.sentence-1)
|
||
|
||
[ð](#lib:operator-,slide_view::sentinel_)
|
||
|
||
`friend constexpr range_difference_t<V>
|
||
operator-(const sentinel& y, const iterator<false>& x)
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[5](#range.slide.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15573)
|
||
|
||
*Returns*: y.*end_* - x.*last_ele_*[.](#range.slide.sentinel-5.sentence-1)
|
||
|
||
### [25.7.31](#range.chunk.by) Chunk by view [[range.chunk.by]](range.chunk.by)
|
||
|
||
#### [25.7.31.1](#range.chunk.by.overview) Overview [[range.chunk.by.overview]](range.chunk.by.overview)
|
||
|
||
[1](#range.chunk.by.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15582)
|
||
|
||
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[.](#range.chunk.by.overview-1.sentence-1)
|
||
|
||
[2](#range.chunk.by.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15588)
|
||
|
||
The name views::chunk_by denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.chunk.by.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and F,
|
||
the expression views::chunk_by(E, F) is expression-equivalent tochunk_by_view(E, F)[.](#range.chunk.by.overview-2.sentence-2)
|
||
|
||
[*Example [1](#range.chunk.by.overview-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](#range.chunk.by.view) Class template chunk_by_view [[range.chunk.by.view]](range.chunk.by.view)
|
||
|
||
[ð](#lib:chunk_by_view)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [indirect_binary_predicate](indirectcallable.indirectinvocable#concept:indirect_binary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<iterator_t<V>, iterator_t<V>> Pred>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<Pred>class chunk_by_view : public view_interface<chunk_by_view<V, Pred>> { V *base_* = V(); // *exposition only**movable-box*<Pred> *pred_*; // *exposition only*// [[range.chunk.by.iter]](#range.chunk.by.iter "25.7.31.3 Class chunk_by_view::iterator"), class chunk_by_view::*iterator*class *iterator*; // *exposition only*public: chunk_by_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<Pred> = default; constexpr explicit chunk_by_view(V base, Pred pred); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr const Pred& pred() const; constexpr *iterator* begin(); constexpr auto end(); constexpr iterator_t<V> *find-next*(iterator_t<V>); // *exposition only*constexpr iterator_t<V> *find-prev*(iterator_t<V>) // *exposition only*requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>; }; template<class R, class Pred> chunk_by_view(R&&, Pred) -> chunk_by_view<views::all_t<R>, Pred>;}
|
||
|
||
[ð](#lib:chunk_by_view,constructor)
|
||
|
||
`constexpr explicit chunk_by_view(V base, Pred pred);
|
||
`
|
||
|
||
[1](#range.chunk.by.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15654)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*pred_* with std::move(pred)[.](#range.chunk.by.view-1.sentence-1)
|
||
|
||
[ð](#lib:pred,chunk_by_view)
|
||
|
||
`constexpr const Pred& pred() const;
|
||
`
|
||
|
||
[2](#range.chunk.by.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15666)
|
||
|
||
*Effects*: Equivalent to: return **pred_*;
|
||
|
||
[ð](#lib:begin,chunk_by_view)
|
||
|
||
`constexpr iterator begin();
|
||
`
|
||
|
||
[3](#range.chunk.by.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15677)
|
||
|
||
*Preconditions*: *pred_*.has_value() is true[.](#range.chunk.by.view-3.sentence-1)
|
||
|
||
[4](#range.chunk.by.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15681)
|
||
|
||
*Returns*: *iterator*(*this, ranges::begin(*base_*), *find-next*(ranges::begin(*base_*)))[.](#range.chunk.by.view-4.sentence-1)
|
||
|
||
[5](#range.chunk.by.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15685)
|
||
|
||
*Remarks*: In order to provide
|
||
the amortized constant-time complexity required by the [range](range.range#concept:range "25.4.2 Ranges [range.range]") concept,
|
||
this function caches the result within the chunk_by_view for use on subsequent calls[.](#range.chunk.by.view-5.sentence-1)
|
||
|
||
[ð](#lib:end,chunk_by_view)
|
||
|
||
`constexpr auto end();
|
||
`
|
||
|
||
[6](#range.chunk.by.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15699)
|
||
|
||
*Effects*: Equivalent to:if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V>) {return *iterator*(*this, ranges::end(*base_*), ranges::end(*base_*));} else {return default_sentinel;}
|
||
|
||
[ð](#lib:find-next,chunk_by_view)
|
||
|
||
`constexpr iterator_t<V> find-next(iterator_t<V> current);
|
||
`
|
||
|
||
[7](#range.chunk.by.view-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15717)
|
||
|
||
*Preconditions*: *pred_*.has_value() is true[.](#range.chunk.by.view-7.sentence-1)
|
||
|
||
[8](#range.chunk.by.view-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15721)
|
||
|
||
*Returns*: ranges::next(ranges::adjacent_find(current, ranges::end(*base_*), not_fn(ref(**pred_*))), 1, ranges::end(*base_*))
|
||
|
||
[ð](#lib:find-prev,chunk_by_view)
|
||
|
||
`constexpr iterator_t<V> find-prev(iterator_t<V> current) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[9](#range.chunk.by.view-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15735)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(9.1)](#range.chunk.by.view-9.1)
|
||
|
||
current is not equal to ranges::begin(*base_*)[.](#range.chunk.by.view-9.1.sentence-1)
|
||
|
||
- [(9.2)](#range.chunk.by.view-9.2)
|
||
|
||
*pred_*.has_value() is true[.](#range.chunk.by.view-9.2.sentence-1)
|
||
|
||
[10](#range.chunk.by.view-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15744)
|
||
|
||
*Returns*: An iterator i in the range [ranges::begin(*base_*), current) such that:
|
||
|
||
- [(10.1)](#range.chunk.by.view-10.1)
|
||
|
||
ranges::adjacent_find(i, current, not_fn(ref(**pred_*))) is equal to current; and
|
||
|
||
- [(10.2)](#range.chunk.by.view-10.2)
|
||
|
||
if i is not equal to ranges::begin(*base_*),
|
||
then bool(invoke(**pred_*, *ranges::prev(i), *i)) is false[.](#range.chunk.by.view-10.sentence-1)
|
||
|
||
#### [25.7.31.3](#range.chunk.by.iter) Class chunk_by_view::*iterator* [[range.chunk.by.iter]](range.chunk.by.iter)
|
||
|
||
[ð](#lib:chunk_by_view::iterator)
|
||
|
||
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") V, [indirect_binary_predicate](indirectcallable.indirectinvocable#concept:indirect_binary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]")<iterator_t<V>, iterator_t<V>> Pred>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V> && is_object_v<Pred>class chunk_by_view<V, Pred>::*iterator* { chunk_by_view* *parent_* = nullptr; // *exposition only* iterator_t<V> *current_* = iterator_t<V>(); // *exposition only* iterator_t<V> *next_* = iterator_t<V>(); // *exposition only*constexpr *iterator*(chunk_by_view& parent, iterator_t<V> current, // *exposition only* iterator_t<V> next); public:using value_type = subrange<iterator_t<V>>; using difference_type = range_difference_t<V>; 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](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>; constexpr *iterator* operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y); friend constexpr bool operator==(const *iterator*& x, default_sentinel_t); };}
|
||
|
||
[1](#range.chunk.by.iter-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15794)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.chunk.by.iter-1.1)
|
||
|
||
If V models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes bidirectional_iterator_tag[.](#range.chunk.by.iter-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.chunk.by.iter-1.2)
|
||
|
||
Otherwise, iterator_concept denotes forward_iterator_tag[.](#range.chunk.by.iter-1.2.sentence-1)
|
||
|
||
[ð](#lib:chunk_by_view::iterator,constructor)
|
||
|
||
`constexpr iterator(chunk_by_view& parent, iterator_t<V> current, iterator_t<V> next);
|
||
`
|
||
|
||
[2](#range.chunk.by.iter-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15810)
|
||
|
||
*Effects*: Initializes *parent_* with addressof(parent),*current_* with current, and*next_* with next[.](#range.chunk.by.iter-2.sentence-1)
|
||
|
||
[ð](#lib:operator*,chunk_by_view::iterator)
|
||
|
||
`constexpr value_type operator*() const;
|
||
`
|
||
|
||
[3](#range.chunk.by.iter-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15823)
|
||
|
||
*Preconditions*: *current_* is not equal to *next_*[.](#range.chunk.by.iter-3.sentence-1)
|
||
|
||
[4](#range.chunk.by.iter-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15827)
|
||
|
||
*Returns*: subrange(*current_*, *next_*)[.](#range.chunk.by.iter-4.sentence-1)
|
||
|
||
[ð](#lib:operator++,chunk_by_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[5](#range.chunk.by.iter-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15838)
|
||
|
||
*Preconditions*: *current_* is not equal to *next_*[.](#range.chunk.by.iter-5.sentence-1)
|
||
|
||
[6](#range.chunk.by.iter-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15842)
|
||
|
||
*Effects*: Equivalent to:*current_* = *next_*;*next_* = *parent_*->*find-next*(*current_*);return *this;
|
||
|
||
[ð](#lib:operator++,chunk_by_view::iterator_)
|
||
|
||
`constexpr iterator operator++(int);
|
||
`
|
||
|
||
[7](#range.chunk.by.iter-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15858)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,chunk_by_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[8](#range.chunk.by.iter-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15874)
|
||
|
||
*Effects*: Equivalent to:*next_* = *current_*;*current_* = *parent_*->*find-prev*(*next_*);return *this;
|
||
|
||
[ð](#lib:operator--,chunk_by_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<V>;
|
||
`
|
||
|
||
[9](#range.chunk.by.iter-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15890)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator==,chunk_by_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y);
|
||
`
|
||
|
||
[10](#range.chunk.by.iter-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15906)
|
||
|
||
*Returns*: x.*current_* == y.*current_*[.](#range.chunk.by.iter-10.sentence-1)
|
||
|
||
[ð](#lib:operator==,chunk_by_view::iterator_)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[11](#range.chunk.by.iter-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15917)
|
||
|
||
*Returns*: x.*current_* == x.*next_*[.](#range.chunk.by.iter-11.sentence-1)
|
||
|
||
### [25.7.32](#range.stride) Stride view [[range.stride]](range.stride)
|
||
|
||
#### [25.7.32.1](#range.stride.overview) Overview [[range.stride.overview]](range.stride.overview)
|
||
|
||
[1](#range.stride.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15926)
|
||
|
||
stride_view presents a view of an underlying sequence,
|
||
advancing over n elements at a time,
|
||
as opposed to the usual single-step succession[.](#range.stride.overview-1.sentence-1)
|
||
|
||
[2](#range.stride.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15931)
|
||
|
||
The name views::stride denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.stride.overview-2.sentence-1)
|
||
|
||
Given subexpressions E and N,
|
||
the expression views::stride(E, N) is expression-equivalent to stride_view(E, N)[.](#range.stride.overview-2.sentence-2)
|
||
|
||
[3](#range.stride.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L15938)
|
||
|
||
[*Example [1](#range.stride.overview-example-1)*: auto input = views::iota(0, 12) | views::stride(3);
|
||
ranges::copy(input, ostream_iterator<int>(cout, " ")); // prints 0 3 6 9 ranges::copy(input | views::reverse, ostream_iterator<int>(cout, " ")); // prints 9 6 3 0 â *end example*]
|
||
|
||
#### [25.7.32.2](#range.stride.view) Class template stride_view [[range.stride.view]](range.stride.view)
|
||
|
||
[ð](#lib:stride_view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class stride_view : public view_interface<stride_view<V>> { V *base_*; // *exposition only* range_difference_t<V> *stride_*; // *exposition only*// [[range.stride.iterator]](#range.stride.iterator "25.7.32.3 Class template stride_view::iterator"), class template stride_view::*iterator*template<bool> class *iterator*; // *exposition only*public:constexpr explicit stride_view(V base, range_difference_t<V> stride); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr range_difference_t<V> stride() const noexcept; constexpr auto begin() requires (<V>) {return *iterator*<false>(this, ranges::begin(*base_*)); }constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {return *iterator*<true>(this, ranges::begin(*base_*)); }constexpr auto end() requires (<V>) {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<V>) {auto missing = (*stride_* - ranges::distance(*base_*) % *stride_*) % *stride_*; return *iterator*<false>(this, ranges::end(*base_*), missing); } else if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<V> && <V>) {return *iterator*<false>(this, ranges::end(*base_*)); } else {return default_sentinel; }}constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V> {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V> && [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<const V>) {auto missing = (*stride_* - ranges::distance(*base_*) % *stride_*) % *stride_*; return *iterator*<true>(this, ranges::end(*base_*), missing); } else if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<const V> && <const V>) {return *iterator*<true>(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]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; 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]")<const V>; }; template<class R> stride_view(R&&, range_difference_t<R>) -> stride_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:stride_view,constructor)
|
||
|
||
`constexpr stride_view(V base, range_difference_t<V> stride);
|
||
`
|
||
|
||
[1](#range.stride.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16015)
|
||
|
||
*Preconditions*: stride > 0 is true[.](#range.stride.view-1.sentence-1)
|
||
|
||
[2](#range.stride.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16019)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base) and*stride_* with stride[.](#range.stride.view-2.sentence-1)
|
||
|
||
[ð](#lib:stride,stride_view)
|
||
|
||
`constexpr range_difference_t<V> stride() const noexcept;
|
||
`
|
||
|
||
[3](#range.stride.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16031)
|
||
|
||
*Returns*: *stride_*[.](#range.stride.view-3.sentence-1)
|
||
|
||
[ð](#lib:size,stride_view)
|
||
|
||
`constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[4](#range.stride.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16043)
|
||
|
||
*Effects*: Equivalent to:return *to-unsigned-like*(*div-ceil*(ranges::distance(*base_*), *stride_*));
|
||
|
||
[ð](#lib:reserve_hint,stride_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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[5](#range.stride.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16058)
|
||
|
||
*Effects*: Equivalent to:auto s = static_cast<range_difference_t<decltype((*base_*))>>(ranges::reserve_hint(*base_*));return *to-unsigned-like*(*div-ceil*(s, *stride_*));
|
||
|
||
#### [25.7.32.3](#range.stride.iterator) Class template stride_view::*iterator* [[range.stride.iterator]](range.stride.iterator)
|
||
|
||
[ð](#lib:stride_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>template<bool Const>class stride_view<V>::*iterator* {using *Parent* = *maybe-const*<Const, stride_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only* sentinel_t<*Base*> *end_* = sentinel_t<*Base*>(); // *exposition only* range_difference_t<*Base*> *stride_* = 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 difference_type = range_difference_t<*Base*>; using value_type = range_value_t<*Base*>; using iterator_concept = *see below*; using iterator_category = *see below*; // not always present*iterator*() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iterator_t<*Base*>> = default; constexpr *iterator*(*iterator*<!Const> other)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>&& [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<*Base*>>; constexpr iterator_t<*Base*> base() &&; constexpr const iterator_t<*Base*>& base() const & noexcept; constexpr decltype(auto) operator*() const { return **current_*; }constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; 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 n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr *iterator*& operator-=(difference_type n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>; constexpr decltype(auto) operator[](difference_type n) constrequires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*Base*>{ return *(*this + n); }friend constexpr bool operator==(const *iterator*& x, default_sentinel_t); friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<*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 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]")<iterator_t<*Base*>>; friend constexpr *iterator* operator+(const *iterator*& x, 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*& x)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*& x, 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*>, 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]")<sentinel_t<*Base*>, 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]")<sentinel_t<*Base*>, iterator_t<*Base*>>; friend constexpr range_rvalue_reference_t<*Base*> iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(i.*current_*))); friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)noexcept(noexcept(ranges::iter_swap(x.*current_*, y.*current_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*Base*>>; };}
|
||
|
||
[1](#range.stride.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16161)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.stride.iterator-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[.](#range.stride.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.stride.iterator-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[.](#range.stride.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.stride.iterator-1.3)
|
||
|
||
Otherwise, if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.stride.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.stride.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.stride.iterator-1.4.sentence-1)
|
||
|
||
[2](#range.stride.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16177)
|
||
|
||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined
|
||
if and only if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.stride.iterator-2.sentence-1)
|
||
|
||
In that case,*iterator*::iterator_category is defined as follows:
|
||
|
||
- [(2.1)](#range.stride.iterator-2.1)
|
||
|
||
Let C denote
|
||
the type iterator_traits<iterator_t<*Base*>>::iterator_category[.](#range.stride.iterator-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.stride.iterator-2.2)
|
||
|
||
If C models[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<random_access_iterator_tag>,
|
||
then iterator_category denotes random_access_iterator_tag[.](#range.stride.iterator-2.2.sentence-1)
|
||
|
||
- [(2.3)](#range.stride.iterator-2.3)
|
||
|
||
Otherwise, iterator_category denotes C[.](#range.stride.iterator-2.3.sentence-1)
|
||
|
||
[ð](#lib:stride_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent* parent, iterator_t<Base> current,
|
||
range_difference_t<Base> missing = 0);
|
||
`
|
||
|
||
[3](#range.stride.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16201)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current),*end_* with ranges::end(parent->*base_*),*stride_* with parent->*stride_*, and*missing_* with missing[.](#range.stride.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:stride_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>
|
||
&& [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<sentinel_t<V>, sentinel_t<Base>>;
|
||
`
|
||
|
||
[4](#range.stride.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16217)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*),*end_* with std::move(i.*end_*),*stride_* with i.*stride_*, and*missing_* with i.*missing_*[.](#range.stride.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:base,stride_view::iterator)
|
||
|
||
`constexpr iterator_t<Base> base() &&;
|
||
`
|
||
|
||
[5](#range.stride.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16231)
|
||
|
||
*Returns*: std::move(*current_*)[.](#range.stride.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:base,stride_view::iterator_)
|
||
|
||
`constexpr const iterator_t<Base>& base() const & noexcept;
|
||
`
|
||
|
||
[6](#range.stride.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16242)
|
||
|
||
*Returns*: *current_*[.](#range.stride.iterator-6.sentence-1)
|
||
|
||
[ð](#lib:operator++,stride_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[7](#range.stride.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16253)
|
||
|
||
*Preconditions*: *current_* != *end_* is true[.](#range.stride.iterator-7.sentence-1)
|
||
|
||
[8](#range.stride.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16257)
|
||
|
||
*Effects*: Equivalent to:*missing_* = ranges::advance(*current_*, *stride_*, *end_*);return *this;
|
||
|
||
[ð](#lib:operator++,stride_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[9](#range.stride.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16272)
|
||
|
||
*Effects*: Equivalent to ++*this;
|
||
|
||
[ð](#lib:operator++,stride_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[10](#range.stride.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16283)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,stride_view::iterator)
|
||
|
||
`constexpr iterator& operator--() requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[11](#range.stride.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16299)
|
||
|
||
*Effects*: Equivalent to:ranges::advance(*current_*, *missing_* - *stride_*);*missing_* = 0;return *this;
|
||
|
||
[ð](#lib:operator--,stride_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int) requires [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[12](#range.stride.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16315)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,stride_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type n) requires [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Base>;
|
||
`
|
||
|
||
[13](#range.stride.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16331)
|
||
|
||
*Preconditions*: If n is positive,ranges::distance(*current_*, *end_*) > *stride_* * (n - 1) is true[.](#range.stride.iterator-13.sentence-1)
|
||
|
||
[*Note [1](#range.stride.iterator-note-1)*:
|
||
|
||
If n is negative, the *Effects* paragraph implies a precondition[.](#range.stride.iterator-13.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[14](#range.stride.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16340)
|
||
|
||
*Effects*: Equivalent to:if (n > 0) { ranges::advance(*current_*, *stride_* * (n - 1)); *missing_* = ranges::advance(*current_*, *stride_*, *end_*);} else if (n < 0) { ranges::advance(*current_*, *stride_* * n + *missing_*); *missing_* = 0;}return *this;
|
||
|
||
[ð](#lib:operator-=,stride_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]")<Base>;
|
||
`
|
||
|
||
[15](#range.stride.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16362)
|
||
|
||
*Effects*: Equivalent to: return *this += -x;
|
||
|
||
[ð](#lib:operator==,stride_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[16](#range.stride.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16373)
|
||
|
||
*Returns*: x.*current_* == x.*end_*[.](#range.stride.iterator-16.sentence-1)
|
||
|
||
[ð](#lib:operator==,stride_view::iterator_)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[17](#range.stride.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16385)
|
||
|
||
*Returns*: x.*current_* == y.*current_*[.](#range.stride.iterator-17.sentence-1)
|
||
|
||
[ð](#lib:operator%3c,stride_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]")<Base>;
|
||
`
|
||
|
||
[18](#range.stride.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16397)
|
||
|
||
*Returns*: x.*current_* < y.*current_*[.](#range.stride.iterator-18.sentence-1)
|
||
|
||
[ð](#lib:operator%3e,stride_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]")<Base>;
|
||
`
|
||
|
||
[19](#range.stride.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16409)
|
||
|
||
*Effects*: Equivalent to: return y < x;
|
||
|
||
[ð](#lib:operator%3c=,stride_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]")<Base>;
|
||
`
|
||
|
||
[20](#range.stride.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16421)
|
||
|
||
*Effects*: Equivalent to: return !(y < x);
|
||
|
||
[ð](#lib:operator%3e=,stride_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]")<Base>;
|
||
`
|
||
|
||
[21](#range.stride.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16433)
|
||
|
||
*Effects*: Equivalent to: return !(x < y);
|
||
|
||
[ð](#lib:operator%3c=%3e,stride_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]")<Base> && [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[22](#range.stride.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16445)
|
||
|
||
*Returns*: x.*current_* <=> y.*current_*[.](#range.stride.iterator-22.sentence-1)
|
||
|
||
[ð](#lib:operator+,stride_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]")<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>;
|
||
`
|
||
|
||
[23](#range.stride.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16459)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r += n;return r;
|
||
|
||
[ð](#lib:operator-,stride_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]")<Base>;
|
||
`
|
||
|
||
[24](#range.stride.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16476)
|
||
|
||
*Effects*: Equivalent to:auto r = i;
|
||
r -= n;return r;
|
||
|
||
[ð](#lib:operator-,stride_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<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[25](#range.stride.iterator-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16493)
|
||
|
||
*Returns*: Let N be (x.*current_* - y.*current_*)[.](#range.stride.iterator-25.sentence-1)
|
||
|
||
- [(25.1)](#range.stride.iterator-25.1)
|
||
|
||
If *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),(N + x.*missing_* - y.*missing_*) / x.*stride_*[.](#range.stride.iterator-25.1.sentence-1)
|
||
|
||
- [(25.2)](#range.stride.iterator-25.2)
|
||
|
||
Otherwise, if N is negative, -*div-ceil*(-N, x.*stride_*)[.](#range.stride.iterator-25.2.sentence-1)
|
||
|
||
- [(25.3)](#range.stride.iterator-25.3)
|
||
|
||
Otherwise, *div-ceil*(N, x.*stride_*)[.](#range.stride.iterator-25.3.sentence-1)
|
||
|
||
[ð](#lib:operator-,stride_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]")<sentinel_t<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[26](#range.stride.iterator-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16514)
|
||
|
||
*Returns*: *div-ceil*(x.*end_* - x.*current_*, x.*stride_*)[.](#range.stride.iterator-26.sentence-1)
|
||
|
||
[ð](#lib:operator-,stride_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]")<sentinel_t<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[27](#range.stride.iterator-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16526)
|
||
|
||
*Effects*: Equivalent to: return -(y - x);
|
||
|
||
[ð](#lib:iter_move,stride_view::iterator)
|
||
|
||
`friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
|
||
noexcept(noexcept(ranges::iter_move(i.current_)));
|
||
`
|
||
|
||
[28](#range.stride.iterator-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16538)
|
||
|
||
*Effects*: Equivalent to: return ranges::iter_move(i.*current_*);
|
||
|
||
[ð](#lib:iter_swap,stride_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
||
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[29](#range.stride.iterator-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16551)
|
||
|
||
*Effects*: Equivalent to:ranges::iter_swap(x.*current_*, y.*current_*);
|
||
|
||
### [25.7.33](#range.cartesian) Cartesian product view [[range.cartesian]](range.cartesian)
|
||
|
||
#### [25.7.33.1](#range.cartesian.overview) Overview [[range.cartesian.overview]](range.cartesian.overview)
|
||
|
||
[1](#range.cartesian.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16562)
|
||
|
||
cartesian_product_view takes any non-zero number of ranges n and
|
||
produces a view of tuples calculated by
|
||
the n-ary cartesian product of the provided ranges[.](#range.cartesian.overview-1.sentence-1)
|
||
|
||
[2](#range.cartesian.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16567)
|
||
|
||
The name views::cartesian_product denotes a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5 Customization Point Object types"))[.](#range.cartesian.overview-2.sentence-1)
|
||
|
||
Given a pack of subexpressions Es,
|
||
the expression views::cartesian_product(Es...) is expression-equivalent to
|
||
|
||
- [(2.1)](#range.cartesian.overview-2.1)
|
||
|
||
views::single(tuple()) if Es is an empty pack,
|
||
|
||
- [(2.2)](#range.cartesian.overview-2.2)
|
||
|
||
otherwise,cartesian_product_view<views::all_t<decltype((Es))>...>(Es...)[.](#range.cartesian.overview-2.sentence-2)
|
||
|
||
[3](#range.cartesian.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16581)
|
||
|
||
[*Example [1](#range.cartesian.overview-example-1)*: vector<int> v { 0, 1, 2 };for (auto&& [a, b, c] : views::cartesian_product(v, v, v)) { cout << a << ' ' << b << ' ' << c << '\n';}// The above prints// 0 0 0// 0 0 1// 0 0 2// 0 1 0// 0 1 1// ... â *end example*]
|
||
|
||
#### [25.7.33.2](#range.cartesian.view) Class template cartesian_product_view [[range.cartesian.view]](range.cartesian.view)
|
||
|
||
[ð](#lib:cartesian_product_view_)
|
||
|
||
namespace std::ranges {template<bool Const, class First, class... Vs>concept [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") = // *exposition only*([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, First>> && ... &&([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Vs>>&& [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<*maybe-const*<Const, Vs>>)); template<class R>concept [*cartesian-product-common-arg*](#concept:cartesian-product-common-arg "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") = // *exposition only*[common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<R> || ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R> && [random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<R>); template<bool Const, class First, class... Vs>concept [*cartesian-product-is-bidirectional*](#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") = // *exposition only*([bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, First>> && ... &&([bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, Vs>>&& [*cartesian-product-common-arg*](#concept:cartesian-product-common-arg "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<*maybe-const*<Const, Vs>>)); template<class First, class...>concept [*cartesian-product-is-common*](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") = // *exposition only*[*cartesian-product-common-arg*](#concept:cartesian-product-common-arg "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First>; template<class... Vs>concept [*cartesian-product-is-sized*](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") = // *exposition only*([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Vs> && ...); template<bool Const, template<class> class FirstSent, class First, class... Vs>concept [*cartesian-is-sized-sentinel*](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") = // *exposition only*([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<FirstSent<*maybe-const*<Const, First>>,
|
||
iterator_t<*maybe-const*<Const, First>>> && ...&& ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<*maybe-const*<Const, Vs>>&& [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<iterator_t<*maybe-const*<Const, Vs>>,
|
||
iterator_t<*maybe-const*<Const, Vs>>>)); template<[*cartesian-product-common-arg*](#concept:cartesian-product-common-arg "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]") R>constexpr auto *cartesian-common-arg-end*(R& r) { // *exposition only*if constexpr ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<R>) {return ranges::end(r); } else {return ranges::begin(r) + ranges::distance(r); }}template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") First, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")... Vs>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<First> && ... && [view](range.view#concept:view "25.4.5 Views [range.view]")<Vs>)class cartesian_product_view : public view_interface<cartesian_product_view<First, Vs...>> {private: tuple<First, Vs...> *bases_*; // *exposition only*// [[range.cartesian.iterator]](#range.cartesian.iterator "25.7.33.3 Class template cartesian_product_view::iterator"), class template cartesian_product_view::*iterator*template<bool Const> class *iterator*; // *exposition only*public:constexpr cartesian_product_view() = default; constexpr explicit cartesian_product_view(First first_base, Vs... bases); constexpr *iterator*<false> begin()requires (<First> || ... || <Vs>); constexpr *iterator*<true> begin() constrequires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const First> && ... && [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Vs>); constexpr *iterator*<false> end()requires ((<First> || ... || <Vs>) &&[*cartesian-product-is-common*](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First, Vs...>); constexpr *iterator*<true> end() constrequires [*cartesian-product-is-common*](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<const First, const Vs...>; constexpr default_sentinel_t end() const noexcept; constexpr *see below* size()requires [*cartesian-product-is-sized*](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First, Vs...>; constexpr *see below* size() constrequires [*cartesian-product-is-sized*](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<const First, const Vs...>; }; template<class... Vs> cartesian_product_view(Vs&&...) -> cartesian_product_view<views::all_t<Vs>...>;}
|
||
|
||
[ð](#lib:cartesian_product_view,constructor)
|
||
|
||
`constexpr explicit cartesian_product_view(First first_base, Vs... bases);
|
||
`
|
||
|
||
[1](#range.cartesian.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16685)
|
||
|
||
*Effects*: Initializes *bases_* with std::move(first_base), std::move(bases)...[.](#range.cartesian.view-1.sentence-1)
|
||
|
||
[ð](#lib:begin,cartesian_product_view)
|
||
|
||
`constexpr iterator<false> begin()
|
||
requires (<First> || ... || <Vs>);
|
||
`
|
||
|
||
[2](#range.cartesian.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16698)
|
||
|
||
*Effects*: Equivalent to:return *iterator*<false>(*this, *tuple-transform*(ranges::begin, *bases_*));
|
||
|
||
[ð](#lib:begin,cartesian_product_view_)
|
||
|
||
`constexpr iterator<true> begin() const
|
||
requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const First> && ... && [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Vs>);
|
||
`
|
||
|
||
[3](#range.cartesian.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16713)
|
||
|
||
*Effects*: Equivalent to:return *iterator*<true>(*this, *tuple-transform*(ranges::begin, *bases_*));
|
||
|
||
[ð](#lib:end,cartesian_product_view)
|
||
|
||
`constexpr iterator<false> end()
|
||
requires ((<First> || ... || <Vs>)
|
||
&& [cartesian-product-is-common](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First, Vs...>);
|
||
constexpr iterator<true> end() const
|
||
requires [cartesian-product-is-common](#concept:cartesian-product-is-common "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<const First, const Vs...>;
|
||
`
|
||
|
||
[4](#range.cartesian.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16731)
|
||
|
||
Let:
|
||
|
||
- [(4.1)](#range.cartesian.view-4.1)
|
||
|
||
*is-const* be true for the const-qualified overload, andfalse otherwise;
|
||
|
||
- [(4.2)](#range.cartesian.view-4.2)
|
||
|
||
*is-empty* be true if the expression ranges::empty(rng) is true for any rng among the underlying ranges except the first one andfalse otherwise; and
|
||
|
||
- [(4.3)](#range.cartesian.view-4.3)
|
||
|
||
*begin-or-first-end*(rng) be expression-equivalent to*is-empty* ? ranges::begin(rng) : *cartesian-common-arg-end*(rng) if rng is the first underlying range andranges::begin(rng) otherwise[.](#range.cartesian.view-4.sentence-1)
|
||
|
||
[5](#range.cartesian.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16749)
|
||
|
||
*Effects*: Equivalent to:*iterator*<*is-const*> it(*this, *tuple-transform*([](auto& rng){ return *begin-or-first-end*(rng); }, *bases_*));return it;
|
||
|
||
[ð](#lib:end,cartesian_product_view_)
|
||
|
||
`constexpr default_sentinel_t end() const noexcept;
|
||
`
|
||
|
||
[6](#range.cartesian.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16765)
|
||
|
||
*Returns*: default_sentinel[.](#range.cartesian.view-6.sentence-1)
|
||
|
||
[ð](#lib:size,cartesian_product_view)
|
||
|
||
`constexpr see below size()
|
||
requires [cartesian-product-is-sized](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<First, Vs...>;
|
||
constexpr see below size() const
|
||
requires [cartesian-product-is-sized](#concept:cartesian-product-is-sized "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<const First, const Vs...>;
|
||
`
|
||
|
||
[7](#range.cartesian.view-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16779)
|
||
|
||
The return type is an implementation-defined unsigned-integer-like type[.](#range.cartesian.view-7.sentence-1)
|
||
|
||
[8](#range.cartesian.view-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16782)
|
||
|
||
*Recommended practice*: The return type should be the smallest unsigned-integer-like type
|
||
that is sufficiently wide to store the product of the maximum sizes of
|
||
all the underlying ranges, if such a type exists[.](#range.cartesian.view-8.sentence-1)
|
||
|
||
[9](#range.cartesian.view-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16788)
|
||
|
||
Let p be the product of the sizes of all the ranges in *bases_*[.](#range.cartesian.view-9.sentence-1)
|
||
|
||
[10](#range.cartesian.view-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16791)
|
||
|
||
*Preconditions*: p can be represented by the return type[.](#range.cartesian.view-10.sentence-1)
|
||
|
||
[11](#range.cartesian.view-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16795)
|
||
|
||
*Returns*: p[.](#range.cartesian.view-11.sentence-1)
|
||
|
||
#### [25.7.33.3](#range.cartesian.iterator) Class template cartesian_product_view::*iterator* [[range.cartesian.iterator]](range.cartesian.iterator)
|
||
|
||
[ð](#lib:cartesian_product_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") First, [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")... Vs>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<First> && ... && [view](range.view#concept:view "25.4.5 Views [range.view]")<Vs>)template<bool Const>class cartesian_product_view<First, Vs...>::*iterator* {public:using iterator_category = input_iterator_tag; using iterator_concept = *see below*; using value_type = tuple<range_value_t<*maybe-const*<Const, First>>,
|
||
range_value_t<*maybe-const*<Const, Vs>>...>; using reference = tuple<range_reference_t<*maybe-const*<Const, First>>,
|
||
range_reference_t<*maybe-const*<Const, Vs>>...>; using difference_type = *see below*; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i) requires Const &&([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<First>, iterator_t<const First>> &&... && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Vs>, iterator_t<const Vs>>); constexpr auto operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<*maybe-const*<Const, First>>; constexpr *iterator*& operator--()requires [*cartesian-product-is-bidirectional*](#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; constexpr *iterator* operator--(int)requires [*cartesian-product-is-bidirectional*](#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; constexpr *iterator*& operator+=(difference_type x)requires [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; constexpr *iterator*& operator-=(difference_type x)requires [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; constexpr reference operator[](difference_type n) constrequires [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<*maybe-const*<Const, First>>>; friend constexpr bool operator==(const *iterator*& x, default_sentinel_t); friend constexpr auto operator<=>(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, First, Vs...>; friend constexpr *iterator* operator+(const *iterator*& x, difference_type y)requires [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr *iterator* operator+(difference_type x, const *iterator*& y)requires [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr *iterator* operator-(const *iterator*& x, difference_type y)requires [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>; friend constexpr difference_type operator-(const *iterator*& x, const *iterator*& y)requires [*cartesian-is-sized-sentinel*](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, iterator_t, First, Vs...>; friend constexpr difference_type operator-(const *iterator*& i, default_sentinel_t)requires [*cartesian-is-sized-sentinel*](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>; friend constexpr difference_type operator-(default_sentinel_t, const *iterator*& i)requires [*cartesian-is-sized-sentinel*](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>; friend constexpr auto iter_move(const *iterator*& i) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& l, const *iterator*& r) noexcept(*see below*)requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, First>>> && ... &&[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, Vs>>>); private:using *Parent* = *maybe-const*<Const, cartesian_product_view>; // *exposition only**Parent** *parent_* = nullptr; // *exposition only* tuple<iterator_t<*maybe-const*<Const, First>>,
|
||
iterator_t<*maybe-const*<Const, Vs>>...> *current_*; // *exposition only*template<size_t N = sizeof...(Vs)>constexpr void *next*(); // *exposition only*template<size_t N = sizeof...(Vs)>constexpr void *prev*(); // *exposition only*template<class Tuple>constexpr difference_type *distance-from*(const Tuple& t) const; // *exposition only*constexpr *iterator*(*Parent*& parent, tuple<iterator_t<*maybe-const*<Const, First>>,
|
||
iterator_t<*maybe-const*<Const, Vs>>...> current); // *exposition only*};}
|
||
|
||
[1](#range.cartesian.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16891)
|
||
|
||
*iterator*::iterator_concept is defined as follows:
|
||
|
||
- [(1.1)](#range.cartesian.iterator-1.1)
|
||
|
||
If [*cartesian-product-is-random-access*](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...> is modeled,
|
||
then iterator_concept denotes random_access_iterator_tag[.](#range.cartesian.iterator-1.1.sentence-1)
|
||
|
||
- [(1.2)](#range.cartesian.iterator-1.2)
|
||
|
||
Otherwise,
|
||
if [*cartesian-product-is-bidirectional*](#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...> is modeled,
|
||
then iterator_concept denotes bidirectional_iterator_tag[.](#range.cartesian.iterator-1.2.sentence-1)
|
||
|
||
- [(1.3)](#range.cartesian.iterator-1.3)
|
||
|
||
Otherwise,
|
||
if *maybe-const*<Const, First> models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]"),
|
||
then iterator_concept denotes forward_iterator_tag[.](#range.cartesian.iterator-1.3.sentence-1)
|
||
|
||
- [(1.4)](#range.cartesian.iterator-1.4)
|
||
|
||
Otherwise, iterator_concept denotes input_iterator_tag[.](#range.cartesian.iterator-1.4.sentence-1)
|
||
|
||
[2](#range.cartesian.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16911)
|
||
|
||
*iterator*::difference_type is
|
||
an implementation-defined
|
||
signed-integer-like type[.](#range.cartesian.iterator-2.sentence-1)
|
||
|
||
[3](#range.cartesian.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16916)
|
||
|
||
*Recommended practice*: *iterator*::difference_type should be
|
||
the smallest signed-integer-like type
|
||
that is sufficiently wide to store
|
||
the product of the maximum sizes of all underlying ranges
|
||
if such a type exists[.](#range.cartesian.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:next,cartesian_product_view)
|
||
|
||
`template<size_t N = sizeof...(Vs)>
|
||
constexpr void next();
|
||
`
|
||
|
||
[4](#range.cartesian.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16931)
|
||
|
||
*Effects*: Equivalent to:auto& it = std::get<N>(*current_*);++it;if constexpr (N > 0) {if (it == ranges::end(std::get<N>(*parent_*->*bases_*))) { it = ranges::begin(std::get<N>(*parent_*->*bases_*)); *next*<N - 1>(); }}
|
||
|
||
[ð](#lib:prev,cartesian_product_view)
|
||
|
||
`template<size_t N = sizeof...(Vs)>
|
||
constexpr void prev();
|
||
`
|
||
|
||
[5](#range.cartesian.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16953)
|
||
|
||
*Effects*: Equivalent to:auto& it = std::get<N>(*current_*);if constexpr (N > 0) {if (it == ranges::begin(std::get<N>(*parent_*->*bases_*))) { it = *cartesian-common-arg-end*(std::get<N>(*parent_*->*bases_*)); *prev*<N - 1>(); }}--it;
|
||
|
||
[ð](#lib:distance-from,cartesian_product_view)
|
||
|
||
`template<class Tuple>
|
||
constexpr difference_type distance-from(const Tuple& t) const;
|
||
`
|
||
|
||
[6](#range.cartesian.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16975)
|
||
|
||
Let:
|
||
|
||
- [(6.1)](#range.cartesian.iterator-6.1)
|
||
|
||
*scaled-size*(N) be the product ofstatic_cast<difference_type>(ranges::size(std::get<N>(*parent_*->*bases_*))) andscaled-size(N+1) if N ⤠sizeof...(Vs), otherwise static_cast<difference_type>(1);
|
||
|
||
- [(6.2)](#range.cartesian.iterator-6.2)
|
||
|
||
*scaled-distance*(N) be the product ofstatic_cast<difference_type>(std::get<N>(*current_*) - std::get<N>(t)) and scaled-size(N+1); and
|
||
|
||
- [(6.3)](#range.cartesian.iterator-6.3)
|
||
|
||
*scaled-sum* be the sum of *scaled-distance*(N) for every integer 0 ⤠N ⤠sizeof...(Vs)[.](#range.cartesian.iterator-6.sentence-1)
|
||
|
||
[7](#range.cartesian.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16991)
|
||
|
||
*Preconditions*: *scaled-sum* can be represented by difference_type[.](#range.cartesian.iterator-7.sentence-1)
|
||
|
||
[8](#range.cartesian.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L16995)
|
||
|
||
*Returns*: *scaled-sum*[.](#range.cartesian.iterator-8.sentence-1)
|
||
|
||
[ð](#lib:cartesian_product_view::iterator,constructor)
|
||
|
||
`constexpr iterator(Parent& parent, tuple<iterator_t<maybe-const<Const, First>>,
|
||
iterator_t<maybe-const<Const, Vs>>...> current);
|
||
`
|
||
|
||
[9](#range.cartesian.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17007)
|
||
|
||
*Effects*: Initializes*parent_* with addressof(parent) and*current_* with std::move(current)[.](#range.cartesian.iterator-9.sentence-1)
|
||
|
||
[ð](#lib:cartesian_product_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i) requires Const &&
|
||
([convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<First>, iterator_t<const First>> &&
|
||
... && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<Vs>, iterator_t<const Vs>>);
|
||
`
|
||
|
||
[10](#range.cartesian.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17022)
|
||
|
||
*Effects*: Initializes*parent_* with i.*parent_* and*current_* with std::move(i.*current_*)[.](#range.cartesian.iterator-10.sentence-1)
|
||
|
||
[ð](#lib:operator*,cartesian_product_view::iterator)
|
||
|
||
`constexpr auto operator*() const;
|
||
`
|
||
|
||
[11](#range.cartesian.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17035)
|
||
|
||
*Effects*: Equivalent to:return *tuple-transform*([](auto& i) -> decltype(auto) { return *i; }, *current_*);
|
||
|
||
[ð](#lib:operator++,cartesian_product_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[12](#range.cartesian.iterator-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17049)
|
||
|
||
*Effects*: Equivalent to:*next*();return *this;
|
||
|
||
[ð](#lib:operator++,cartesian_product_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[13](#range.cartesian.iterator-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17064)
|
||
|
||
*Effects*: Equivalent to ++*this[.](#range.cartesian.iterator-13.sentence-1)
|
||
|
||
[ð](#lib:operator++,cartesian_product_view::iterator__)
|
||
|
||
`constexpr iterator operator++(int) requires [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<maybe-const<Const, First>>;
|
||
`
|
||
|
||
[14](#range.cartesian.iterator-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17075)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
|
||
|
||
[ð](#lib:operator--,cartesian_product_view::iterator)
|
||
|
||
`constexpr iterator& operator--()
|
||
requires [cartesian-product-is-bidirectional](#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[15](#range.cartesian.iterator-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17092)
|
||
|
||
*Effects*: Equivalent to:*prev*();return *this;
|
||
|
||
[ð](#lib:operator--,cartesian_product_view::iterator_)
|
||
|
||
`constexpr iterator operator--(int)
|
||
requires [cartesian-product-is-bidirectional](#concept:cartesian-product-is-bidirectional "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[16](#range.cartesian.iterator-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17108)
|
||
|
||
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
|
||
|
||
[ð](#lib:operator+=,cartesian_product_view::iterator)
|
||
|
||
`constexpr iterator& operator+=(difference_type x)
|
||
requires [cartesian-product-is-random-access](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[17](#range.cartesian.iterator-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17125)
|
||
|
||
Let orig be the value of *this before the call[.](#range.cartesian.iterator-17.sentence-1)
|
||
|
||
Let ret be:
|
||
|
||
- [(17.1)](#range.cartesian.iterator-17.1)
|
||
|
||
If x > 0,
|
||
the value of *this had *next* been called x times[.](#range.cartesian.iterator-17.1.sentence-1)
|
||
|
||
- [(17.2)](#range.cartesian.iterator-17.2)
|
||
|
||
Otherwise, if x < 0,
|
||
the value of *this had *prev* been called -x times[.](#range.cartesian.iterator-17.2.sentence-1)
|
||
|
||
- [(17.3)](#range.cartesian.iterator-17.3)
|
||
|
||
Otherwise, orig[.](#range.cartesian.iterator-17.3.sentence-1)
|
||
|
||
[18](#range.cartesian.iterator-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17140)
|
||
|
||
*Preconditions*: x is in the range[ranges::distance(*this, ranges::begin(**parent_*)),
|
||
ranges::distance(*this, ranges::end(**parent_*))][.](#range.cartesian.iterator-18.sentence-1)
|
||
|
||
[19](#range.cartesian.iterator-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17146)
|
||
|
||
*Effects*: Sets the value of *this to ret[.](#range.cartesian.iterator-19.sentence-1)
|
||
|
||
[20](#range.cartesian.iterator-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17150)
|
||
|
||
*Returns*: *this[.](#range.cartesian.iterator-20.sentence-1)
|
||
|
||
[21](#range.cartesian.iterator-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17154)
|
||
|
||
*Complexity*: Constant[.](#range.cartesian.iterator-21.sentence-1)
|
||
|
||
[ð](#lib:operator-=,cartesian_product_view::iterator)
|
||
|
||
`constexpr iterator& operator-=(difference_type x)
|
||
requires [cartesian-product-is-random-access](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[22](#range.cartesian.iterator-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17166)
|
||
|
||
*Effects*: Equivalent to:*this += -x;return *this;
|
||
|
||
[ð](#lib:operator%5b%5d,cartesian_product_view::iterator)
|
||
|
||
`constexpr reference operator[](difference_type n) const
|
||
requires [cartesian-product-is-random-access](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[23](#range.cartesian.iterator-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17182)
|
||
|
||
*Effects*: Equivalent to: return *((*this) + n);
|
||
|
||
[ð](#lib:operator==,cartesian_product_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const iterator& y)
|
||
requires [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<iterator_t<maybe-const<Const, First>>>;
|
||
`
|
||
|
||
[24](#range.cartesian.iterator-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17194)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* == y.*current_*;
|
||
|
||
[ð](#lib:operator==,cartesian_product_view::iterator_)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, default_sentinel_t);
|
||
`
|
||
|
||
[25](#range.cartesian.iterator-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17205)
|
||
|
||
*Returns*: true if std::get<i>(x.*current_*) == ranges::end(std::get<i>(x.*parent_*->*bases_*)) is true for any integer 0 ⤠i ⤠sizeof...(Vs);
|
||
otherwise, false[.](#range.cartesian.iterator-25.sentence-1)
|
||
|
||
[ð](#lib:operator%3c=%3e,cartesian_product_view::iterator)
|
||
|
||
`friend constexpr auto operator<=>(const iterator& x, const iterator& y)
|
||
requires [all-random-access](#concept:all-random-access "25.7.5 Range adaptor helpers [range.adaptor.helpers]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[26](#range.cartesian.iterator-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17220)
|
||
|
||
*Effects*: Equivalent to: return x.*current_* <=> y.*current_*;
|
||
|
||
[ð](#lib:operator+,cartesian_product_view::iterator)
|
||
|
||
`friend constexpr iterator operator+(const iterator& x, difference_type y)
|
||
requires [cartesian-product-is-random-access](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[27](#range.cartesian.iterator-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17232)
|
||
|
||
*Effects*: Equivalent to: return *iterator*(x) += y;
|
||
|
||
[ð](#lib:operator+,cartesian_product_view::iterator_)
|
||
|
||
`friend constexpr iterator operator+(difference_type x, const iterator& y)
|
||
requires [cartesian-product-is-random-access](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[28](#range.cartesian.iterator-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17244)
|
||
|
||
*Effects*: Equivalent to: return y + x;
|
||
|
||
[ð](#lib:operator-,cartesian_product_view::iterator)
|
||
|
||
`friend constexpr iterator operator-(const iterator& x, difference_type y)
|
||
requires [cartesian-product-is-random-access](#concept:cartesian-product-is-random-access "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, First, Vs...>;
|
||
`
|
||
|
||
[29](#range.cartesian.iterator-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17256)
|
||
|
||
*Effects*: Equivalent to: return *iterator*(x) -= y;
|
||
|
||
[ð](#lib:operator-,cartesian_product_view::iterator_)
|
||
|
||
`friend constexpr difference_type operator-(const iterator& x, const iterator& y)
|
||
requires [cartesian-is-sized-sentinel](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, iterator_t, First, Vs...>;
|
||
`
|
||
|
||
[30](#range.cartesian.iterator-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17268)
|
||
|
||
*Effects*: Equivalent to: return x.*distance-from*(y.*current_*);
|
||
|
||
[ð](#lib:operator-,cartesian_product_view::iterator__)
|
||
|
||
`friend constexpr difference_type operator-(const iterator& i, default_sentinel_t)
|
||
requires [cartesian-is-sized-sentinel](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>;
|
||
`
|
||
|
||
[31](#range.cartesian.iterator-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17280)
|
||
|
||
Let *end-tuple* be an object of a type
|
||
that is a specialization of tuple, such that:
|
||
|
||
- [(31.1)](#range.cartesian.iterator-31.1)
|
||
|
||
std::get<0>(*end-tuple*) has the same value asranges::end(std::get<0>(i.*parent_*->*bases_*));
|
||
|
||
- [(31.2)](#range.cartesian.iterator-31.2)
|
||
|
||
std::get<N>(*end-tuple*) has the same value asranges::begin(std::get<N>(i.*parent_*->*bases_*)) for every integer 1 ⤠N ⤠sizeof...(Vs)[.](#range.cartesian.iterator-31.sentence-1)
|
||
|
||
[32](#range.cartesian.iterator-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17293)
|
||
|
||
*Effects*: Equivalent to: return i.*distance-from*(*end-tuple*);
|
||
|
||
[ð](#lib:operator-,cartesian_product_view::iterator___)
|
||
|
||
`friend constexpr difference_type operator-(default_sentinel_t s, const iterator& i)
|
||
requires [cartesian-is-sized-sentinel](#concept:cartesian-is-sized-sentinel "25.7.33.2 Class template cartesian_product_view [range.cartesian.view]")<Const, sentinel_t, First, Vs...>;
|
||
`
|
||
|
||
[33](#range.cartesian.iterator-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17305)
|
||
|
||
*Effects*: Equivalent to: return -(i - s);
|
||
|
||
[ð](#lib:iter_move,cartesian_product_view::iterator)
|
||
|
||
`friend constexpr auto iter_move(const iterator& i) noexcept(see below);
|
||
`
|
||
|
||
[34](#range.cartesian.iterator-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17316)
|
||
|
||
*Effects*: Equivalent to: return *tuple-transform*(ranges::iter_move, i.*current_*);
|
||
|
||
[35](#range.cartesian.iterator-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17320)
|
||
|
||
*Remarks*: The exception specification is equivalent to
|
||
the logical and of the following expressions:
|
||
|
||
- [(35.1)](#range.cartesian.iterator-35.1)
|
||
|
||
noexcept(ranges::iter_move(std::get<N>(i.*current_*))) for every integer
|
||
0 ⤠N ⤠sizeof...(Vs),
|
||
|
||
- [(35.2)](#range.cartesian.iterator-35.2)
|
||
|
||
is_nothrow_move_constructible_v<range_rvalue_reference_t<*maybe-const*<Const, T>>>
|
||
for every type T in First, Vs...[.](#range.cartesian.iterator-35.sentence-1)
|
||
|
||
[ð](#lib:iter_swap,cartesian_product_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
|
||
requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<maybe-const<Const, First>>> && ... &&
|
||
[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<maybe-const<Const, Vs>>>);
|
||
`
|
||
|
||
[36](#range.cartesian.iterator-36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17342)
|
||
|
||
*Effects*: For every integer 0 ⤠i ⤠sizeof...(Vs), performs:ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))
|
||
|
||
[37](#range.cartesian.iterator-37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17349)
|
||
|
||
*Remarks*: The exception specification is equivalent to the logical and of the following expressions:
|
||
|
||
- [(37.1)](#range.cartesian.iterator-37.1)
|
||
|
||
noexcept(ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))) for
|
||
every integer 0 ⤠i ⤠sizeof...(Vs)[.](#range.cartesian.iterator-37.sentence-1)
|
||
|
||
### [25.7.34](#range.cache.latest) Cache latest view [[range.cache.latest]](range.cache.latest)
|
||
|
||
#### [25.7.34.1](#range.cache.latest.overview) Overview [[range.cache.latest.overview]](range.cache.latest.overview)
|
||
|
||
[1](#range.cache.latest.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17363)
|
||
|
||
cache_latest_view caches the last-accessed element of
|
||
its underlying sequence
|
||
so that the element does not have to be recomputed on repeated access[.](#range.cache.latest.overview-1.sentence-1)
|
||
|
||
[*Note [1](#range.cache.latest.overview-note-1)*:
|
||
|
||
This is useful if computation of the element to produce is expensive[.](#range.cache.latest.overview-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#range.cache.latest.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17371)
|
||
|
||
The name views::cache_latest denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.cache.latest.overview-2.sentence-1)
|
||
|
||
Let E be an expression[.](#range.cache.latest.overview-2.sentence-2)
|
||
|
||
The expression views::cache_latest(E) is expression-equivalent tocache_latest_view(E)[.](#range.cache.latest.overview-2.sentence-3)
|
||
|
||
#### [25.7.34.2](#range.cache.latest.view) Class template cache_latest_view [[range.cache.latest.view]](range.cache.latest.view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class [cache_latest_view](#lib:cache_latest_view "25.7.34.2 Class template cache_latest_view [range.cache.latest.view]") : public view_interface<cache_latest_view<V>> { V *base_* = V(); // *exposition only*using *cache-t* = conditional_t<is_reference_v<range_reference_t<V>>, // *exposition only* add_pointer_t<range_reference_t<V>>,
|
||
range_reference_t<V>>; *non-propagating-cache*<*cache-t*> *cache_*; // *exposition only*// [[range.cache.latest.iterator]](#range.cache.latest.iterator "25.7.34.3 Class cache_latest_view::iterator"), class cache_latest_view::*iterator*class *iterator*; // *exposition only*// [[range.cache.latest.sentinel]](#range.cache.latest.sentinel "25.7.34.4 Class cache_latest_view::sentinel"), class cache_latest_view::*sentinel*class *sentinel*; // *exposition only*public: cache_latest_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit cache_latest_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin(); constexpr auto end(); constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; 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]")<const V>; }; template<class R> cache_latest_view(R&&) -> cache_latest_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:cache_latest_view,constructor)
|
||
|
||
`constexpr explicit cache_latest_view(V base);
|
||
`
|
||
|
||
[1](#range.cache.latest.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17425)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.cache.latest.view-1.sentence-1)
|
||
|
||
[ð](#lib:begin,cache_latest_view)
|
||
|
||
`constexpr auto begin();
|
||
`
|
||
|
||
[2](#range.cache.latest.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17436)
|
||
|
||
*Effects*: Equivalent to: return *iterator*(*this);
|
||
|
||
[ð](#lib:end,cache_latest_view)
|
||
|
||
`constexpr auto end();
|
||
`
|
||
|
||
[3](#range.cache.latest.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17447)
|
||
|
||
*Effects*: Equivalent to: return *sentinel*(*this);
|
||
|
||
[ð](#lib:size,cache_latest_view)
|
||
|
||
`constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[4](#range.cache.latest.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17459)
|
||
|
||
*Effects*: Equivalent to: return ranges::size(*base_*);
|
||
|
||
[ð](#lib:reserve_hint,cache_latest_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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[5](#range.cache.latest.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17471)
|
||
|
||
*Effects*: Equivalent to: return ranges::reserve_hint(*base_*);
|
||
|
||
#### [25.7.34.3](#range.cache.latest.iterator) Class cache_latest_view::*iterator* [[range.cache.latest.iterator]](range.cache.latest.iterator)
|
||
|
||
[ð](#lib:cache_latest_view::iiterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class cache_latest_view<V>::*iterator* { cache_latest_view* *parent_*; // *exposition only* iterator_t<V> *current_*; // *exposition only*constexpr explicit *iterator*(cache_latest_view& parent); // *exposition only*public:using difference_type = range_difference_t<V>; using value_type = range_value_t<V>; using iterator_concept = input_iterator_tag; *iterator*(*iterator*&&) = default; *iterator*& operator=(*iterator*&&) = default; constexpr iterator_t<V> base() &&; constexpr const iterator_t<V>& base() const & noexcept; constexpr range_reference_t<V>& operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); friend constexpr range_rvalue_reference_t<V> iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(i.*current_*))); friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)noexcept(noexcept(ranges::iter_swap(x.*current_*, y.*current_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<V>>; };}
|
||
|
||
[ð](#lib:cache_latest_view::iterator,constructor)
|
||
|
||
`constexpr explicit iterator(cache_latest_view& parent);
|
||
`
|
||
|
||
[1](#range.cache.latest.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17521)
|
||
|
||
*Effects*: Initializes *current_* withranges::begin(parent.*base_*) and *parent_* with addressof(parent)[.](#range.cache.latest.iterator-1.sentence-1)
|
||
|
||
[ð](#lib:base,cache_latest_view::iterator)
|
||
|
||
`constexpr iterator_t<V> base() &&;
|
||
`
|
||
|
||
[2](#range.cache.latest.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17534)
|
||
|
||
*Returns*: std::move(*current_*)[.](#range.cache.latest.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:base,cache_latest_view::iterator_)
|
||
|
||
`constexpr const iterator_t<V>& base() const & noexcept;
|
||
`
|
||
|
||
[3](#range.cache.latest.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17545)
|
||
|
||
*Returns*: *current_*[.](#range.cache.latest.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:operator++,cache_latest_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[4](#range.cache.latest.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17556)
|
||
|
||
*Effects*: Equivalent to:*parent_*->*cache_*.reset();++*current_*;return *this;
|
||
|
||
[ð](#lib:operator++,cache_latest_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[5](#range.cache.latest.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17572)
|
||
|
||
*Effects*: Equivalent to: ++*this[.](#range.cache.latest.iterator-5.sentence-1)
|
||
|
||
[ð](#lib:operator*,cache_latest_view::iterator)
|
||
|
||
`constexpr range_reference_t<V>& operator*() const;
|
||
`
|
||
|
||
[6](#range.cache.latest.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17583)
|
||
|
||
*Effects*: Equivalent to:if constexpr (is_reference_v<range_reference_t<V>>) {if (!*parent_*->*cache_*) {*parent_*->*cache_* = addressof(*as-lvalue*(**current_*)); }return ***parent_*->*cache_*;} else {if (!*parent_*->c*ache_*) {*parent_*->*cache_*.*emplace-deref*(*current_*); }return **parent_*->*cache_*;}
|
||
|
||
[*Note [1](#range.cache.latest.iterator-note-1)*:
|
||
|
||
Evaluations of operator* on the same iterator object
|
||
can conflict ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#range.cache.latest.iterator-6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:iter_move,cache_latest_view::iterator)
|
||
|
||
`friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
|
||
noexcept(noexcept(ranges::iter_move(i.current_)));
|
||
`
|
||
|
||
[7](#range.cache.latest.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17612)
|
||
|
||
*Effects*: Equivalent to: return ranges::iter_move(i.*current_*);
|
||
|
||
[ð](#lib:iter_swap,cache_latest_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
||
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<V>>;
|
||
`
|
||
|
||
[8](#range.cache.latest.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17625)
|
||
|
||
*Effects*: Equivalent toranges::iter_swap(x.*current_*, y.*current_*)[.](#range.cache.latest.iterator-8.sentence-1)
|
||
|
||
#### [25.7.34.4](#range.cache.latest.sentinel) Class cache_latest_view::*sentinel* [[range.cache.latest.sentinel]](range.cache.latest.sentinel)
|
||
|
||
[ð](#lib:cache_latest_view::sentinel)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class cache_latest_view<V>::*sentinel* { sentinel_t<V> *end_* = sentinel_t<V>(); // *exposition only*constexpr explicit *sentinel*(cache_latest_view& parent); // *exposition only*public:*sentinel*() = default; constexpr sentinel_t<V> base() const; friend constexpr bool operator==(const *iterator*& x, const *sentinel*& y); friend constexpr range_difference_t<V> operator-(const *iterator*& x, const *sentinel*& y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>; friend constexpr range_difference_t<V> operator-(const *sentinel*& 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]")<sentinel_t<V>, iterator_t<V>>; };}
|
||
|
||
[ð](#lib:cache_latest_view::sentinel,constructor)
|
||
|
||
`constexpr explicit sentinel(cache_latest_view& parent);
|
||
`
|
||
|
||
[1](#range.cache.latest.sentinel-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17664)
|
||
|
||
*Effects*: Initializes *end_* with ranges::end(parent.*base_*)[.](#range.cache.latest.sentinel-1.sentence-1)
|
||
|
||
[ð](#lib:base,cache_latest_view::sentinel)
|
||
|
||
`constexpr sentinel_t<V> base() const;
|
||
`
|
||
|
||
[2](#range.cache.latest.sentinel-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17675)
|
||
|
||
*Returns*: *end_*[.](#range.cache.latest.sentinel-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,cache_latest_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const sentinel& y);
|
||
`
|
||
|
||
[3](#range.cache.latest.sentinel-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17687)
|
||
|
||
*Returns*: x.*current_* == y.*end_*[.](#range.cache.latest.sentinel-3.sentence-1)
|
||
|
||
[ð](#lib:operator-,cache_latest_view::iterator)
|
||
|
||
`friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[4](#range.cache.latest.sentinel-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17700)
|
||
|
||
*Returns*: x.*current_* - y.*end_*[.](#range.cache.latest.sentinel-4.sentence-1)
|
||
|
||
[ð](#lib:operator-,cache_latest_view::iterator_)
|
||
|
||
`friend constexpr range_difference_t<V> operator-(const sentinel& 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]")<sentinel_t<V>, iterator_t<V>>;
|
||
`
|
||
|
||
[5](#range.cache.latest.sentinel-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17713)
|
||
|
||
*Returns*: x.*end_* - y.*current_*[.](#range.cache.latest.sentinel-5.sentence-1)
|
||
|
||
### [25.7.35](#range.to.input) To input view [[range.to.input]](range.to.input)
|
||
|
||
#### [25.7.35.1](#range.to.input.overview) Overview [[range.to.input.overview]](range.to.input.overview)
|
||
|
||
[1](#range.to.input.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17722)
|
||
|
||
to_input_view presents a view of an underlying sequence
|
||
as an input-only non-common range[.](#range.to.input.overview-1.sentence-1)
|
||
|
||
[*Note [1](#range.to.input.overview-note-1)*:
|
||
|
||
This is useful to avoid overhead
|
||
that can be necessary to provide support for the operations
|
||
needed for greater iterator strength[.](#range.to.input.overview-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#range.to.input.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17731)
|
||
|
||
The name views::to_input denotes
|
||
a range adaptor object ([[range.adaptor.object]](#range.adaptor.object "25.7.2 Range adaptor objects"))[.](#range.to.input.overview-2.sentence-1)
|
||
|
||
Let E be an expression and let T be decltype((E))[.](#range.to.input.overview-2.sentence-2)
|
||
|
||
The expression views::to_input(E) is expression-equivalent to:
|
||
|
||
- [(2.1)](#range.to.input.overview-2.1)
|
||
|
||
views::all(E) if T models [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]"),
|
||
does not satisfy [common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]"), and
|
||
does not satisfy [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]")[.](#range.to.input.overview-2.1.sentence-1)
|
||
|
||
- [(2.2)](#range.to.input.overview-2.2)
|
||
|
||
Otherwise, to_input_view(E)[.](#range.to.input.overview-2.2.sentence-1)
|
||
|
||
#### [25.7.35.2](#range.to.input.view) Class template to_input_view [[range.to.input.view]](range.to.input.view)
|
||
|
||
[ð](#lib:to_input_view)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>class to_input_view : public view_interface<to_input_view<V>> { V *base_* = V(); // *exposition only*// [[range.to.input.iterator]](#range.to.input.iterator "25.7.35.3 Class template to_input_view::iterator"), class template to_input_view::*iterator*template<bool Const> class *iterator*; // *exposition only*public: to_input_view() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<V> = default; constexpr explicit to_input_view(V base); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr auto begin() requires (<V>); constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>; constexpr auto end() requires (<V>); constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>; constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>; constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>; constexpr auto reserve_hint() requires [approximately_sized_range](range.approximately.sized#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<V>; 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]")<const V>; }; template<class R> to_input_view(R&&) -> to_input_view<views::all_t<R>>;}
|
||
|
||
[ð](#lib:to_input_view,constructor)
|
||
|
||
`constexpr explicit to_input_view(V base);
|
||
`
|
||
|
||
[1](#range.to.input.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17790)
|
||
|
||
*Effects*: Initializes *base_* with std::move(base)[.](#range.to.input.view-1.sentence-1)
|
||
|
||
[ð](#lib:begin,to_input_view)
|
||
|
||
`constexpr auto begin() requires (<V>);
|
||
`
|
||
|
||
[2](#range.to.input.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17801)
|
||
|
||
*Effects*: Equivalent to: return *iterator*<false>(ranges::begin(*base_*));
|
||
|
||
[ð](#lib:begin,to_input_view_)
|
||
|
||
`constexpr auto begin() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>;
|
||
`
|
||
|
||
[3](#range.to.input.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17812)
|
||
|
||
*Effects*: Equivalent to: return *iterator*<true>(ranges::begin(*base_*));
|
||
|
||
[ð](#lib:end,to_input_view)
|
||
|
||
`constexpr auto end() requires (<V>);
|
||
constexpr auto end() const requires [range](range.range#concept:range "25.4.2 Ranges [range.range]")<const V>;
|
||
`
|
||
|
||
[4](#range.to.input.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17824)
|
||
|
||
*Effects*: Equivalent to: return ranges::end(*base_*);
|
||
|
||
[ð](#lib:size,to_input_view)
|
||
|
||
`constexpr auto size() requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<V>;
|
||
constexpr auto size() const requires [sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const V>;
|
||
`
|
||
|
||
[5](#range.to.input.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17836)
|
||
|
||
*Effects*: Equivalent to: return ranges::size(*base_*);
|
||
|
||
[ð](#lib:reserve_hint,to_input_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]")<V>;
|
||
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]")<const V>;
|
||
`
|
||
|
||
[6](#range.to.input.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17848)
|
||
|
||
*Effects*: Equivalent to: return ranges::reserve_hint(*base_*);
|
||
|
||
#### [25.7.35.3](#range.to.input.iterator) Class template to_input_view::*iterator* [[range.to.input.iterator]](range.to.input.iterator)
|
||
|
||
[ð](#lib:to_input_view::iterator)
|
||
|
||
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") V>requires [view](range.view#concept:view "25.4.5 Views [range.view]")<V>template<bool Const>class to_input_view<V>::*iterator* {using *Base* = *maybe-const*<Const, V>; // *exposition only* iterator_t<*Base*> *current_* = iterator_t<*Base*>(); // *exposition only*constexpr explicit *iterator*(iterator_t<*Base*> current); // *exposition only*public:using difference_type = range_difference_t<*Base*>; using value_type = range_value_t<*Base*>; using iterator_concept = input_iterator_tag; *iterator*() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iterator_t<*Base*>> = default; *iterator*(*iterator*&&) = default; *iterator*& operator=(*iterator*&&) = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<*Base*>>; constexpr iterator_t<*Base*> base() &&; constexpr const iterator_t<*Base*>& base() const & noexcept; constexpr decltype(auto) operator*() const { return **current_*; }constexpr *iterator*& operator++(); constexpr void operator++(int); friend constexpr bool operator==(const *iterator*& x, const sentinel_t<*Base*>& y); friend constexpr difference_type operator-(const sentinel_t<*Base*>& 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]")<sentinel_t<*Base*>, iterator_t<*Base*>>; friend constexpr difference_type operator-(const *iterator*& x, const sentinel_t<*Base*>& y)requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<*Base*>, iterator_t<*Base*>>; friend constexpr range_rvalue_reference_t<*Base*> iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(i.*current_*))); friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)noexcept(noexcept(ranges::iter_swap(x.*current_*, y.*current_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<*Base*>>; };}
|
||
|
||
[ð](#lib:to_input_view::iterator,constructor)
|
||
|
||
`constexpr explicit iterator(iterator_t<Base> current);
|
||
`
|
||
|
||
[1](#range.to.input.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17912)
|
||
|
||
*Effects*: Initializes *current_* with std::move(current)[.](#range.to.input.iterator-1.sentence-1)
|
||
|
||
[ð](#lib:to_input_view::iterator,constructor_)
|
||
|
||
`constexpr iterator(iterator<!Const> i)
|
||
requires Const && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<iterator_t<V>, iterator_t<Base>>;
|
||
`
|
||
|
||
[2](#range.to.input.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17924)
|
||
|
||
*Effects*: Initializes *current_* with std::move(i.*current_*)[.](#range.to.input.iterator-2.sentence-1)
|
||
|
||
[ð](#lib:base,to_input_view::iterator)
|
||
|
||
`constexpr iterator_t<Base> base() &&;
|
||
`
|
||
|
||
[3](#range.to.input.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17935)
|
||
|
||
*Returns*: std::move(*current_)*[.](#range.to.input.iterator-3.sentence-1)
|
||
|
||
[ð](#lib:base,to_input_view::iterator_)
|
||
|
||
`constexpr const iterator_t<Base>& base() const & noexcept;
|
||
`
|
||
|
||
[4](#range.to.input.iterator-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17946)
|
||
|
||
*Returns*: *current_*[.](#range.to.input.iterator-4.sentence-1)
|
||
|
||
[ð](#lib:operator++,to_input_view::iterator)
|
||
|
||
`constexpr iterator& operator++();
|
||
`
|
||
|
||
[5](#range.to.input.iterator-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17957)
|
||
|
||
*Effects*: Equivalent to:++*current_*;return *this;
|
||
|
||
[ð](#lib:operator++,to_input_view::iterator_)
|
||
|
||
`constexpr void operator++(int);
|
||
`
|
||
|
||
[6](#range.to.input.iterator-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17972)
|
||
|
||
*Effects*: Equivalent to: ++*this;
|
||
|
||
[ð](#lib:operator==,to_input_view::iterator)
|
||
|
||
`friend constexpr bool operator==(const iterator& x, const sentinel_t<Base>& y);
|
||
`
|
||
|
||
[7](#range.to.input.iterator-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17983)
|
||
|
||
*Returns*: x.*current_* == y[.](#range.to.input.iterator-7.sentence-1)
|
||
|
||
[ð](#lib:operator-,to_input_view::iterator)
|
||
|
||
`friend constexpr difference_type operator-(const sentinel_t<Base>& 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]")<sentinel_t<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[8](#range.to.input.iterator-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L17995)
|
||
|
||
*Returns*: y - x.*current_*[.](#range.to.input.iterator-8.sentence-1)
|
||
|
||
[ð](#lib:operator-,to_input_view::iterator_)
|
||
|
||
`friend constexpr difference_type operator-(const iterator& x, const sentinel_t<Base>& y)
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<sentinel_t<Base>, iterator_t<Base>>;
|
||
`
|
||
|
||
[9](#range.to.input.iterator-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18007)
|
||
|
||
*Returns*: x.*current_* - y[.](#range.to.input.iterator-9.sentence-1)
|
||
|
||
[ð](#lib:iter_move,to_input_view::iterator)
|
||
|
||
`friend constexpr range_rvalue_reference_t<Base> iter_move(const iterator& i)
|
||
noexcept(noexcept(ranges::iter_move(i.current_)));
|
||
`
|
||
|
||
[10](#range.to.input.iterator-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18019)
|
||
|
||
*Effects*: Equivalent to: return ranges::iter_move(i.*current_*);
|
||
|
||
[ð](#lib:iter_swap,to_input_view::iterator)
|
||
|
||
`friend constexpr void iter_swap(const iterator& x, const iterator& y)
|
||
noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
|
||
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<iterator_t<Base>>;
|
||
`
|
||
|
||
[11](#range.to.input.iterator-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L18032)
|
||
|
||
*Effects*: Equivalent to: ranges::iter_swap(x.*current_*, y.*current_*);
|