544 lines
28 KiB
Markdown
544 lines
28 KiB
Markdown
[range.req]
|
||
|
||
# 25 Ranges library [[ranges]](./#ranges)
|
||
|
||
## 25.4 Range requirements [range.req]
|
||
|
||
### [25.4.1](#general) General [[range.req.general]](range.req.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1287)
|
||
|
||
Ranges are an abstraction that allows a C++ program
|
||
to operate on elements of data structures uniformly[.](#general-1.sentence-1)
|
||
|
||
Calling ranges::begin on a range returns an object
|
||
whose type models [input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_or_output_iterator [iterator.concept.iterator]") ([[iterator.concept.iterator]](iterator.concept.iterator "24.3.4.6 Concept input_or_output_iterator"))[.](#general-1.sentence-2)
|
||
|
||
Calling ranges::end on a range returns an object whose type S,
|
||
together with the type I of the object returned by ranges::begin,
|
||
models [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<S, I>[.](#general-1.sentence-3)
|
||
|
||
The library formalizes the interfaces, semantics, and complexity of ranges
|
||
to enable algorithms and range adaptors that work efficiently
|
||
on different types of sequences[.](#general-1.sentence-4)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1299)
|
||
|
||
The [range](#concept:range "25.4.2 Ranges [range.range]") concept requires thatranges::begin and ranges::end return an iterator and a sentinel, respectively[.](#general-2.sentence-1)
|
||
|
||
The [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]") concept refines [range](#concept:range "25.4.2 Ranges [range.range]") with
|
||
the requirement that ranges::size be amortized O(1)[.](#general-2.sentence-2)
|
||
|
||
The [view](#concept:view "25.4.5 Views [range.view]") concept specifies requirements on
|
||
a [range](#concept:range "25.4.2 Ranges [range.range]") type to provide operations with predictable complexity[.](#general-2.sentence-3)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1308)
|
||
|
||
Several refinements of [range](#concept:range "25.4.2 Ranges [range.range]") group requirements
|
||
that arise frequently in concepts and algorithms[.](#general-3.sentence-1)
|
||
|
||
Common ranges are ranges for whichranges::begin and ranges::end return objects of the same type[.](#general-3.sentence-2)
|
||
|
||
Random access ranges are ranges for which ranges::begin returns a type that models[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13 Concept random_access_iterator"))[.](#general-3.sentence-3)
|
||
|
||
(Contiguous, bidirectional, forward, input, and output ranges
|
||
are defined similarly[.](#general-3.sentence-4))
|
||
|
||
Viewable ranges can be converted to views[.](#general-3.sentence-5)
|
||
|
||
### [25.4.2](#range.range) Ranges [[range.range]](range.range)
|
||
|
||
[1](#range.range-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1323)
|
||
|
||
The [range](#concept:range "25.4.2 Ranges [range.range]") concept defines the requirements of a type that allows
|
||
iteration over its elements by providing an iterator and sentinel
|
||
that denote the elements of the range[.](#range.range-1.sentence-1)
|
||
|
||
[ð](#concept:range)
|
||
|
||
`template<class T>
|
||
concept [range](#concept:range "25.4.2 Ranges [range.range]") =
|
||
requires(T& t) {
|
||
ranges::begin(t); // sometimes equality-preserving (see below)
|
||
ranges::end(t);
|
||
};
|
||
`
|
||
|
||
[2](#range.range-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1338)
|
||
|
||
Given an expression t such that decltype((t)) is T&,T models [range](#concept:range "25.4.2 Ranges [range.range]") only if
|
||
|
||
- [(2.1)](#range.range-2.1)
|
||
|
||
[ranges::begin(t), ranges::end(t))
|
||
denotes a range ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")),
|
||
|
||
- [(2.2)](#range.range-2.2)
|
||
|
||
bothranges::begin(t) andranges::end(t) are amortized constant time and non-modifying, and
|
||
|
||
- [(2.3)](#range.range-2.3)
|
||
|
||
if the type of ranges::begin(t) models[forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]"), ranges::begin(t) is equality-preserving[.](#range.range-2.sentence-1)
|
||
|
||
[3](#range.range-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1355)
|
||
|
||
[*Note [1](#range.range-note-1)*:
|
||
|
||
Equality preservation of both ranges::begin andranges::end enables passing a range whose iterator
|
||
type models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]") to multiple
|
||
algorithms and making multiple passes over the range by repeated calls toranges::begin and ranges::end[.](#range.range-3.sentence-1)
|
||
|
||
Since ranges::begin is not required to be equality-preserving
|
||
when the return type does not model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]"),
|
||
it is possible for repeated calls
|
||
to not return equal values or to not be well-defined[.](#range.range-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#concept:borrowed_range)
|
||
|
||
`template<class T>
|
||
concept [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<T> && (is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
|
||
`
|
||
|
||
[4](#range.range-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1376)
|
||
|
||
Let U be remove_reference_t<T> if T is an rvalue reference type, and T otherwise[.](#range.range-4.sentence-1)
|
||
|
||
Given a variable u of type U,T models [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]") only if
|
||
the validity of iterators obtained from u is not tied to the lifetime of that variable[.](#range.range-4.sentence-2)
|
||
|
||
[5](#range.range-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1384)
|
||
|
||
[*Note [2](#range.range-note-2)*:
|
||
|
||
Since the validity of iterators is not tied to the lifetime of
|
||
a variable whose type models [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]"),
|
||
a function with a parameter of such a type can
|
||
return iterators obtained from it without danger of dangling[.](#range.range-5.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:enable_borrowed_range)
|
||
|
||
`template<class>
|
||
constexpr bool enable_borrowed_range = false;
|
||
`
|
||
|
||
[6](#range.range-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1400)
|
||
|
||
*Remarks*: Pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"), users may specialize enable_borrowed_range for cv-unqualified program-defined types[.](#range.range-6.sentence-1)
|
||
|
||
Such specializations shall be
|
||
usable in constant expressions ([[expr.const]](expr.const "7.7 Constant expressions")) and
|
||
have type const bool[.](#range.range-6.sentence-2)
|
||
|
||
[7](#range.range-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1408)
|
||
|
||
[*Example [1](#range.range-example-1)*:
|
||
|
||
Each specialization S of class template subrange ([[range.subrange]](range.subrange "25.5.4 Sub-ranges"))
|
||
models [borrowed_range](#concept:borrowed_range "25.4.2 Ranges [range.range]") because
|
||
|
||
- [(7.1)](#range.range-7.1)
|
||
|
||
enable_borrowed_range<S> is specialized
|
||
to have the value true, and
|
||
|
||
- [(7.2)](#range.range-7.2)
|
||
|
||
S's iterators
|
||
do not have validity tied to the lifetime of an S object
|
||
because they are âborrowedâ from some other range[.](#range.range-7.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
### [25.4.3](#range.approximately.sized) Approximately sized ranges [[range.approximately.sized]](range.approximately.sized)
|
||
|
||
[1](#range.approximately.sized-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1427)
|
||
|
||
The [approximately_sized_range](#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]") concept refines [range](#concept:range "25.4.2 Ranges [range.range]") with the requirement that
|
||
an approximation of the number of elements in the range
|
||
can be determined in amortized constant time using ranges::reserve_hint[.](#range.approximately.sized-1.sentence-1)
|
||
|
||
[ð](#concept:approximately_sized_range)
|
||
|
||
`template<class T>
|
||
concept [approximately_sized_range](#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<T> && requires(T& t) { ranges::reserve_hint(t); };
|
||
`
|
||
|
||
[2](#range.approximately.sized-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1440)
|
||
|
||
Given an lvalue t of type remove_reference_t<T>,T models [approximately_sized_range](#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]") only if
|
||
|
||
- [(2.1)](#range.approximately.sized-2.1)
|
||
|
||
ranges::reserve_hint(t) is amortized O(1),
|
||
does not modify t, and
|
||
has a value that
|
||
is not negative and is representable in range_difference_t<T>, and
|
||
|
||
- [(2.2)](#range.approximately.sized-2.2)
|
||
|
||
if iterator_t<T> models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]"),ranges::reserve_hint(t) is well-defined
|
||
regardless of the evaluation of ranges::begin(t)[.](#range.approximately.sized-2.sentence-1)
|
||
[*Note [1](#range.approximately.sized-note-1)*:
|
||
ranges::reserve_hint(t) is otherwise not required to be well-defined
|
||
after evaluating ranges::begin(t)[.](#range.approximately.sized-2.2.sentence-2)
|
||
For example,
|
||
it is possible for ranges::reserve_hint(t) to be well-defined for
|
||
an [approximately_sized_range](#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]") whose
|
||
iterator type does not model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]") only if evaluated before the first call to ranges::begin(t)[.](#range.approximately.sized-2.2.sentence-3)
|
||
â *end note*]
|
||
|
||
### [25.4.4](#range.sized) Sized ranges [[range.sized]](range.sized)
|
||
|
||
[1](#range.sized-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1467)
|
||
|
||
The [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]") concept
|
||
refines [approximately_sized_range](#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]") with
|
||
the requirement that the number of elements in the range can be determined
|
||
in amortized constant time using ranges::size[.](#range.sized-1.sentence-1)
|
||
|
||
[ð](#concept:sized_range)
|
||
|
||
`template<class T>
|
||
concept [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]") =
|
||
[approximately_sized_range](#concept:approximately_sized_range "25.4.3 Approximately sized ranges [range.approximately.sized]")<T> && requires(T& t) { ranges::size(t); };
|
||
`
|
||
|
||
[2](#range.sized-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1480)
|
||
|
||
Given an lvalue t of type remove_reference_t<T>, T models [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]") only if
|
||
|
||
- [(2.1)](#range.sized-2.1)
|
||
|
||
ranges::size(t) is amortized O(1), does not modify t,
|
||
and is equal to ranges::distance(ranges::begin(t), ranges::end(t)), and
|
||
|
||
- [(2.2)](#range.sized-2.2)
|
||
|
||
if iterator_t<T> models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]"),ranges::size(t) is well-defined regardless of the evaluation ofranges::begin(t)[.](#range.sized-2.sentence-1)
|
||
[*Note [1](#range.sized-note-1)*:
|
||
ranges::size(t) is otherwise not required to be
|
||
well-defined after evaluating ranges::begin(t)[.](#range.sized-2.2.sentence-2)
|
||
For example, it is possible for ranges::size(t) to be well-defined
|
||
for a [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]") whose iterator type
|
||
does not model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]") only if evaluated before the first call to ranges::begin(t)[.](#range.sized-2.2.sentence-3)
|
||
â *end note*]
|
||
|
||
[ð](#lib:disable_sized_range)
|
||
|
||
`template<class>
|
||
constexpr bool disable_sized_range = false;
|
||
`
|
||
|
||
[3](#range.sized-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1508)
|
||
|
||
*Remarks*: Pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"),
|
||
users may specialize disable_sized_range for cv-unqualified program-defined types[.](#range.sized-3.sentence-1)
|
||
|
||
Such specializations shall
|
||
be usable in constant expressions ([[expr.const]](expr.const "7.7 Constant expressions")) and
|
||
have type const bool[.](#range.sized-3.sentence-2)
|
||
|
||
[4](#range.sized-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1517)
|
||
|
||
[*Note [2](#range.sized-note-2)*:
|
||
|
||
disable_sized_range allows use of [range](#concept:range "25.4.2 Ranges [range.range]") types with the library
|
||
that satisfy but do not in fact model [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]")[.](#range.sized-4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
### [25.4.5](#range.view) Views [[range.view]](range.view)
|
||
|
||
[1](#range.view-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1526)
|
||
|
||
The [view](#concept:view "25.4.5 Views [range.view]") concept specifies the requirements of a [range](#concept:range "25.4.2 Ranges [range.range]") type
|
||
that has the semantic properties below,
|
||
which make it suitable for use in
|
||
constructing range adaptor pipelines ([[range.adaptors]](range.adaptors "25.7 Range adaptors"))[.](#range.view-1.sentence-1)
|
||
|
||
[ð](#concept:view)
|
||
|
||
`template<class T>
|
||
concept [view](#concept:view "25.4.5 Views [range.view]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<T> && [movable](concepts.object#concept:movable "18.6 Object concepts [concepts.object]")<T> && enable_view<T>;
|
||
`
|
||
|
||
[2](#range.view-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1539)
|
||
|
||
T models [view](#concept:view "25.4.5 Views [range.view]") only if
|
||
|
||
- [(2.1)](#range.view-2.1)
|
||
|
||
T has O(1) move construction; and
|
||
|
||
- [(2.2)](#range.view-2.2)
|
||
|
||
move assignment of an object of type T is no more complex than destruction followed by move construction; and
|
||
|
||
- [(2.3)](#range.view-2.3)
|
||
|
||
if N copies and/or moves are made from an object of type T that contained M elements,
|
||
then those N objects have O(N+M) destruction; and
|
||
|
||
- [(2.4)](#range.view-2.4)
|
||
|
||
[copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<T> is false, orT has O(1) copy construction; and
|
||
|
||
- [(2.5)](#range.view-2.5)
|
||
|
||
[copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<T> is false, or
|
||
copy assignment of an object of type T is no more complex than destruction followed by copy construction[.](#range.view-2.sentence-1)
|
||
|
||
[3](#range.view-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1564)
|
||
|
||
[*Note [1](#range.view-note-1)*:
|
||
|
||
The constraints on copying and moving imply that
|
||
a moved-from object of type T has O(1) destruction[.](#range.view-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[4](#range.view-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1570)
|
||
|
||
[*Example [1](#range.view-example-1)*:
|
||
|
||
Examples of views are:
|
||
|
||
- [(4.1)](#range.view-4.1)
|
||
|
||
A [range](#concept:range "25.4.2 Ranges [range.range]") type that wraps a pair of iterators[.](#range.view-4.1.sentence-1)
|
||
|
||
- [(4.2)](#range.view-4.2)
|
||
|
||
A [range](#concept:range "25.4.2 Ranges [range.range]") type that holds its elements by shared_ptr and shares ownership with all its copies[.](#range.view-4.2.sentence-1)
|
||
|
||
- [(4.3)](#range.view-4.3)
|
||
|
||
A [range](#concept:range "25.4.2 Ranges [range.range]") type that generates its elements on demand[.](#range.view-4.3.sentence-1)
|
||
|
||
A container such as vector<string> does not meet the semantic requirements of [view](#concept:view "25.4.5 Views [range.view]") since copying the container copies all of the elements,
|
||
which cannot be done in constant time[.](#range.view-4.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[5](#range.view-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1589)
|
||
|
||
Since the difference between [range](#concept:range "25.4.2 Ranges [range.range]") and [view](#concept:view "25.4.5 Views [range.view]") is largely
|
||
semantic, the two are differentiated with the help of enable_view[.](#range.view-5.sentence-1)
|
||
|
||
[ð](#lib:enable_view)
|
||
|
||
`template<class T>
|
||
constexpr bool is-derived-from-view-interface = see below; // exposition only
|
||
template<class T>
|
||
constexpr bool enable_view =
|
||
[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<T, view_base> || is-derived-from-view-interface<T>;
|
||
`
|
||
|
||
[6](#range.view-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1603)
|
||
|
||
For a type T,*is-derived-from-view-interface*<T> is true if and only ifT has exactly one public base class view_interface<U> for some type U andT has no base classes of type view_interface<V> for any other type V[.](#range.view-6.sentence-1)
|
||
|
||
[7](#range.view-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1612)
|
||
|
||
*Remarks*: Pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"), users may specialize enable_view to true for cv-unqualified program-defined types that model [view](#concept:view "25.4.5 Views [range.view]"),
|
||
and false for types that do not[.](#range.view-7.sentence-1)
|
||
|
||
Such specializations shall
|
||
be usable in constant expressions ([[expr.const]](expr.const "7.7 Constant expressions")) and
|
||
have type const bool[.](#range.view-7.sentence-2)
|
||
|
||
### [25.4.6](#range.refinements) Other range refinements [[range.refinements]](range.refinements)
|
||
|
||
[1](#range.refinements-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1625)
|
||
|
||
The [output_range](#concept:output_range "25.4.6 Other range refinements [range.refinements]") concept specifies requirements of a[range](#concept:range "25.4.2 Ranges [range.range]") type for which ranges::begin returns
|
||
a model of [output_iterator](iterator.concept.output#concept:output_iterator "24.3.4.10 Concept output_iterator [iterator.concept.output]") ([[iterator.concept.output]](iterator.concept.output "24.3.4.10 Concept output_iterator"))[.](#range.refinements-1.sentence-1)
|
||
|
||
[input_range](#concept:input_range "25.4.6 Other range refinements [range.refinements]"), [forward_range](#concept:forward_range "25.4.6 Other range refinements [range.refinements]"), [bidirectional_range](#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]"),
|
||
and [random_access_range](#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") are defined similarly[.](#range.refinements-1.sentence-2)
|
||
|
||
[ð](#range.refinements-itemdecl:1)
|
||
|
||
`template<class R, class T>
|
||
concept [output_range](#concept:output_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<R> && [output_iterator](iterator.concept.output#concept:output_iterator "24.3.4.10 Concept output_iterator [iterator.concept.output]")<iterator_t<R>, T>;
|
||
|
||
template<class T>
|
||
concept [input_range](#concept:input_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<T> && [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]")<iterator_t<T>>;
|
||
|
||
template<class T>
|
||
concept [forward_range](#concept:forward_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[input_range](#concept:input_range "25.4.6 Other range refinements [range.refinements]")<T> && [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]")<iterator_t<T>>;
|
||
|
||
template<class T>
|
||
concept [bidirectional_range](#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[forward_range](#concept:forward_range "25.4.6 Other range refinements [range.refinements]")<T> && [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_iterator [iterator.concept.bidir]")<iterator_t<T>>;
|
||
|
||
template<class T>
|
||
concept [random_access_range](#concept:random_access_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[bidirectional_range](#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<T> && [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]")<iterator_t<T>>;
|
||
`
|
||
|
||
[2](#range.refinements-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1654)
|
||
|
||
[contiguous_range](#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") additionally requires that
|
||
the ranges::data customization point object ([[range.prim.data]](range.prim.data "25.3.14 ranges::data"))
|
||
is usable with the range[.](#range.refinements-2.sentence-1)
|
||
|
||
[ð](#concept:contiguous_range)
|
||
|
||
`template<class T>
|
||
concept [contiguous_range](#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[random_access_range](#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<T> && [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_iterator [iterator.concept.contiguous]")<iterator_t<T>> &&
|
||
requires(T& t) {
|
||
{ ranges::data(t) } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<add_pointer_t<range_reference_t<T>>>;
|
||
};
|
||
`
|
||
|
||
[3](#range.refinements-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1668)
|
||
|
||
Given an expression t such that decltype((t)) is T&,T models [contiguous_range](#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") only ifto_address(ranges::begin(t)) == ranges::data(t) is true[.](#range.refinements-3.sentence-1)
|
||
|
||
[4](#range.refinements-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1674)
|
||
|
||
The [common_range](#concept:common_range "25.4.6 Other range refinements [range.refinements]") concept specifies requirements of
|
||
a [range](#concept:range "25.4.2 Ranges [range.range]") type for which ranges::begin andranges::end return objects of the same type[.](#range.refinements-4.sentence-1)
|
||
|
||
[*Example [1](#range.refinements-example-1)*:
|
||
|
||
The standard containers ([[containers]](containers "23 Containers library")) model [common_range](#concept:common_range "25.4.6 Other range refinements [range.refinements]")[.](#range.refinements-4.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[ð](#concept:common_range)
|
||
|
||
`template<class T>
|
||
concept [common_range](#concept:common_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<T> && [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<iterator_t<T>, sentinel_t<T>>;
|
||
`
|
||
|
||
[ð](#range.refinements-itemdecl:4)
|
||
|
||
`template<class R>
|
||
constexpr bool is-initializer-list = see below; // exposition only
|
||
`
|
||
|
||
[5](#range.refinements-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1694)
|
||
|
||
For a type R,*is-initializer-list*<R> is true if and only ifremove_cvref_t<R> is a specialization of initializer_list[.](#range.refinements-5.sentence-1)
|
||
|
||
[6](#range.refinements-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1700)
|
||
|
||
The [viewable_range](#concept:viewable_range "25.4.6 Other range refinements [range.refinements]") concept specifies the requirements of a[range](#concept:range "25.4.2 Ranges [range.range]") type that can be converted to a view safely[.](#range.refinements-6.sentence-1)
|
||
|
||
[ð](#concept:viewable_range)
|
||
|
||
`template<class T>
|
||
concept [viewable_range](#concept:viewable_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[range](#concept:range "25.4.2 Ranges [range.range]")<T> &&
|
||
(([view](#concept:view "25.4.5 Views [range.view]")<remove_cvref_t<T>> && [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<remove_cvref_t<T>, T>) ||
|
||
(<remove_cvref_t<T>> &&
|
||
(is_lvalue_reference_v<T> || ([movable](concepts.object#concept:movable "18.6 Object concepts [concepts.object]")<remove_reference_t<T>> && !is-initializer-list<T>))));
|
||
`
|
||
|
||
[7](#range.refinements-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1713)
|
||
|
||
The [constant_range](#concept:constant_range "25.4.6 Other range refinements [range.refinements]") concept specifies the requirements of a[range](#concept:range "25.4.2 Ranges [range.range]") type whose elements are not modifiable[.](#range.refinements-7.sentence-1)
|
||
|
||
[ð](#concept:constant_range)
|
||
|
||
`template<class T>
|
||
concept [constant_range](#concept:constant_range "25.4.6 Other range refinements [range.refinements]") =
|
||
[input_range](#concept:input_range "25.4.6 Other range refinements [range.refinements]")<T> && [constant-iterator](const.iterators.alias#concept:constant-iterator "24.5.3.2 Alias templates [const.iterators.alias]")<iterator_t<T>>;
|
||
`
|
||
|
||
[8](#range.refinements-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1723)
|
||
|
||
The exposition-only concept [*sized-random-access-range*](#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") specifies the requirements of a [range](#concept:range "25.4.2 Ranges [range.range]") type
|
||
that is sized and allows random access to its elements[.](#range.refinements-8.sentence-1)
|
||
|
||
[ð](#concept:sized-random-access-range)
|
||
|
||
`template<class T>
|
||
concept [sized-random-access-range](#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") = // exposition only
|
||
[random_access_range](#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<R> && [sized_range](#concept:sized_range "25.4.4 Sized ranges [range.sized]")<R>;
|
||
`
|
||
|
||
[*Note [1](#range.refinements-note-1)*:
|
||
|
||
This concept constrains some parallel algorithm overloads;
|
||
see [[algorithms]](algorithms "26 Algorithms library")[.](#range.refinements-sentence-1)
|
||
|
||
â *end note*]
|