This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

543
cppdraft/range/req.md Normal file
View File

@@ -0,0 +1,543 @@
[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.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") ([[iterator.concept.iterator]](iterator.concept.iterator "24.3.4.6Concept 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.7Concept 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.2Ranges[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.4Sized ranges[range.sized]") concept refines [range](#concept:range "25.4.2Ranges[range.range]") with
the requirement that ranges::size be amortized O(1)[.](#general-2.sentence-2)
The [view](#concept:view "25.4.5Views[range.view]") concept specifies requirements on
a [range](#concept:range "25.4.2Ranges[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.2Ranges[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.13Concept random_­access_­iterator[iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept 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.2Ranges[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.2Ranges[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.2Ranges[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.1General")),
- [(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.11Concept 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.11Concept 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.11Concept 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.2Ranges[range.range]") =
[range](#concept:range "25.4.2Ranges[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.2Ranges[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.2Ranges[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.1Namespace 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.7Constant 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.4Sub-ranges"))
models [borrowed_range](#concept:borrowed_range "25.4.2Ranges[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.3Approximately sized ranges[range.approximately.sized]") concept refines [range](#concept:range "25.4.2Ranges[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.3Approximately sized ranges[range.approximately.sized]") =
[range](#concept:range "25.4.2Ranges[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.3Approximately 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.11Concept 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.3Approximately sized ranges[range.approximately.sized]") whose
iterator type does not model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept 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.4Sized ranges[range.sized]") concept
refines [approximately_sized_range](#concept:approximately_sized_range "25.4.3Approximately 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.4Sized ranges[range.sized]") =
[approximately_sized_range](#concept:approximately_sized_range "25.4.3Approximately 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.4Sized 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.11Concept 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.4Sized ranges[range.sized]") whose iterator type
does not model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept 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.1Namespace 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.7Constant 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.2Ranges[range.range]") types with the library
that satisfy but do not in fact model [sized_range](#concept:sized_range "25.4.4Sized 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.5Views[range.view]") concept specifies the requirements of a [range](#concept:range "25.4.2Ranges[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.7Range adaptors"))[.](#range.view-1.sentence-1)
[🔗](#concept:view)
`template<class T>
concept [view](#concept:view "25.4.5Views[range.view]") =
[range](#concept:range "25.4.2Ranges[range.range]")<T> && [movable](concepts.object#concept:movable "18.6Object 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.5Views[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.14Concept 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.6Object 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.2Ranges[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.2Ranges[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.2Ranges[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.5Views[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.2Ranges[range.range]") and [view](#concept:view "25.4.5Views[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.3Concept 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.1Namespace std"), users may specialize enable_view to true for cv-unqualified program-defined types that model [view](#concept:view "25.4.5Views[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.7Constant 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.6Other range refinements[range.refinements]") concept specifies requirements of a[range](#concept:range "25.4.2Ranges[range.range]") type for which ranges::begin returns
a model of [output_iterator](iterator.concept.output#concept:output_iterator "24.3.4.10Concept output_­iterator[iterator.concept.output]") ([[iterator.concept.output]](iterator.concept.output "24.3.4.10Concept output_­iterator"))[.](#range.refinements-1.sentence-1)
[input_range](#concept:input_range "25.4.6Other range refinements[range.refinements]"), [forward_range](#concept:forward_range "25.4.6Other range refinements[range.refinements]"), [bidirectional_range](#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]"),
and [random_access_range](#concept:random_access_range "25.4.6Other 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.6Other range refinements[range.refinements]") =
[range](#concept:range "25.4.2Ranges[range.range]")<R> && [output_iterator](iterator.concept.output#concept:output_iterator "24.3.4.10Concept output_­iterator[iterator.concept.output]")<iterator_t<R>, T>;
template<class T>
concept [input_range](#concept:input_range "25.4.6Other range refinements[range.refinements]") =
[range](#concept:range "25.4.2Ranges[range.range]")<T> && [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]")<iterator_t<T>>;
template<class T>
concept [forward_range](#concept:forward_range "25.4.6Other range refinements[range.refinements]") =
[input_range](#concept:input_range "25.4.6Other range refinements[range.refinements]")<T> && [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")<iterator_t<T>>;
template<class T>
concept [bidirectional_range](#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]") =
[forward_range](#concept:forward_range "25.4.6Other range refinements[range.refinements]")<T> && [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]")<iterator_t<T>>;
template<class T>
concept [random_access_range](#concept:random_access_range "25.4.6Other range refinements[range.refinements]") =
[bidirectional_range](#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<T> && [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept 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.6Other range refinements[range.refinements]") additionally requires that
the ranges::data customization point object ([[range.prim.data]](range.prim.data "25.3.14ranges::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.6Other range refinements[range.refinements]") =
[random_access_range](#concept:random_access_range "25.4.6Other range refinements[range.refinements]")<T> && [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")<iterator_t<T>> &&
requires(T& t) {
{ ranges::data(t) } -> [same_as](concept.same#concept:same_as "18.4.2Concept 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.6Other 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.6Other range refinements[range.refinements]") concept specifies requirements of
a [range](#concept:range "25.4.2Ranges[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 "23Containers library")) model [common_range](#concept:common_range "25.4.6Other 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.6Other range refinements[range.refinements]") =
[range](#concept:range "25.4.2Ranges[range.range]")<T> && [same_as](concept.same#concept:same_as "18.4.2Concept 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.6Other range refinements[range.refinements]") concept specifies the requirements of a[range](#concept:range "25.4.2Ranges[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.6Other range refinements[range.refinements]") =
[range](#concept:range "25.4.2Ranges[range.range]")<T> &&
(([view](#concept:view "25.4.5Views[range.view]")<remove_cvref_t<T>> && [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<remove_cvref_t<T>, T>) ||
(![view](#concept:view "25.4.5Views[range.view]")<remove_cvref_t<T>> &&
(is_lvalue_reference_v<T> || ([movable](concepts.object#concept:movable "18.6Object 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.6Other range refinements[range.refinements]") concept specifies the requirements of a[range](#concept:range "25.4.2Ranges[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.6Other range refinements[range.refinements]") =
[input_range](#concept:input_range "25.4.6Other range refinements[range.refinements]")<T> && [constant-iterator](const.iterators.alias#concept:constant-iterator "24.5.3.2Alias 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.6Other range refinements[range.refinements]") specifies the requirements of a [range](#concept:range "25.4.2Ranges[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.6Other range refinements[range.refinements]") = // exposition only
[random_access_range](#concept:random_access_range "25.4.6Other range refinements[range.refinements]")<R> && [sized_range](#concept:sized_range "25.4.4Sized ranges[range.sized]")<R>;
`
[*Note [1](#range.refinements-note-1)*:
This concept constrains some parallel algorithm overloads;
see [[algorithms]](algorithms "26Algorithms library")[.](#range.refinements-sentence-1)
— *end note*]