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

749 lines
33 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[range.access]
# 25 Ranges library [[ranges]](./#ranges)
## 25.3 Range access [range.access]
### [25.3.1](#general) General [[range.access.general]](range.access.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L633)
In addition to being available via inclusion of the [<ranges>](ranges.syn#header:%3cranges%3e "25.2Header <ranges> synopsis[ranges.syn]") header, the customization point objects in [range.access] are
available when the header [<iterator>](iterator.synopsis#header:%3citerator%3e "24.2Header <iterator>&nbsp;synopsis[iterator.synopsis]") is included[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L638)
Within [range.access],
the [*reified object*](#def:object,reified "25.3.1General[range.access.general]") of a subexpression E denotes
- [(2.1)](#general-2.1)
the same object as E if E is a glvalue, or
- [(2.2)](#general-2.2)
the result of applying
the temporary materialization conversion ([[conv.rval]](conv.rval "7.3.5Temporary materialization conversion")) to E otherwise[.](#general-2.sentence-1)
### [25.3.2](#begin) ranges::begin [[range.access.begin]](range.access.begin)
[1](#begin-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L652)
The name ranges::begin denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#begin-1.sentence-1)
[2](#begin-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L656)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#begin-2.sentence-1)
Then:
- [(2.1)](#begin-2.1)
If E is an rvalue and enable_borrowed_range<remove_cv_t<T>> is false, ranges::begin(E) is ill-formed[.](#begin-2.1.sentence-1)
- [(2.2)](#begin-2.2)
Otherwise, if T is an array type ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")) and remove_all_extents_t<T> is an incomplete type, ranges::begin(E) is ill-formed with no diagnostic required[.](#begin-2.2.sentence-1)
- [(2.3)](#begin-2.3)
Otherwise, if T is an array type, ranges::begin(E) is expression-equivalent to t + 0[.](#begin-2.3.sentence-1)
- [(2.4)](#begin-2.4)
Otherwise, if auto(t.begin()) is a valid expression 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]"), ranges::begin(E) is expression-equivalent to auto(t.begin())[.](#begin-2.4.sentence-1)
- [(2.5)](#begin-2.5)
Otherwise, if T is a class or enumeration type and auto(begin(t)) is a valid expression 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]") where the meaning of begin is established as-if by performing
argument-dependent lookup only ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")),
then ranges::begin(E) is expression-equivalent to
that expression[.](#begin-2.5.sentence-1)
- [(2.6)](#begin-2.6)
Otherwise, ranges::begin(E) is ill-formed[.](#begin-2.6.sentence-1)
[3](#begin-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L696)
[*Note [1](#begin-note-1)*:
Diagnosable ill-formed cases above
result in substitution failure when ranges::begin(E) appears in the immediate context of a template instantiation[.](#begin-3.sentence-1)
— *end note*]
[4](#begin-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L703)
[*Note [2](#begin-note-2)*:
Whenever ranges::begin(E) is a valid expression, its 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]")[.](#begin-4.sentence-1)
— *end note*]
### [25.3.3](#end) ranges::end [[range.access.end]](range.access.end)
[1](#end-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L712)
The name ranges::end denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#end-1.sentence-1)
[2](#end-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L716)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#end-2.sentence-1)
Then:
- [(2.1)](#end-2.1)
If E is an rvalue and enable_borrowed_range<remove_cv_t<T>> is false, ranges::end(E) is ill-formed[.](#end-2.1.sentence-1)
- [(2.2)](#end-2.2)
Otherwise, if T is an array type ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")) and remove_all_extents_t<T> is an incomplete type, ranges::end(E) is ill-formed with no diagnostic required[.](#end-2.2.sentence-1)
- [(2.3)](#end-2.3)
Otherwise, if T is an array of unknown bound, ranges::end(E) is ill-formed[.](#end-2.3.sentence-1)
- [(2.4)](#end-2.4)
Otherwise, if T is an array, ranges::end(E) is expression-equivalent to t + extent_v<T>[.](#end-2.4.sentence-1)
- [(2.5)](#end-2.5)
Otherwise, if auto(t.end()) is a valid expression whose type models [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<iterator_t<T>> then ranges::end(E) is expression-equivalent to auto(t.end())[.](#end-2.5.sentence-1)
- [(2.6)](#end-2.6)
Otherwise, if T is a class or enumeration type and auto(end(t)) is a valid expression whose type models [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<iterator_t<T>> where the meaning of end is established as-if by performing
argument-dependent lookup only ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")),
then ranges::end(E) is expression-equivalent to
that expression[.](#end-2.6.sentence-1)
- [(2.7)](#end-2.7)
Otherwise, ranges::end(E) is ill-formed[.](#end-2.7.sentence-1)
[3](#end-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L761)
[*Note [1](#end-note-1)*:
Diagnosable ill-formed cases above
result in substitution failure when ranges::end(E) appears in the immediate context of a template instantiation[.](#end-3.sentence-1)
— *end note*]
[4](#end-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L768)
[*Note [2](#end-note-2)*:
Whenever ranges::end(E) is a valid expression,
the types S and I ofranges::end(E) and ranges::begin(E) model [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I>[.](#end-4.sentence-1)
— *end note*]
### [25.3.4](#cbegin) ranges::cbegin [[range.access.cbegin]](range.access.cbegin)
[1](#cbegin-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L779)
The name ranges::cbegin denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#cbegin-1.sentence-1)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#cbegin-1.sentence-2)
Then:
- [(1.1)](#cbegin-1.1)
If E is an rvalue andenable_borrowed_range<remove_cv_t<T>> is false,ranges::cbegin(E) is ill-formed[.](#cbegin-1.1.sentence-1)
- [(1.2)](#cbegin-1.2)
Otherwise,
let U be ranges::begin(*possibly-const-range*(t))[.](#cbegin-1.2.sentence-1)
ranges::cbegin(E) is expression-equivalent toconst_iterator<decltype(U)>(U)[.](#cbegin-1.2.sentence-2)
[2](#cbegin-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L797)
[*Note [1](#cbegin-note-1)*:
Whenever ranges::cbegin(E) is a valid expression, its 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]") and [*constant-iterator*](const.iterators.alias#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]")[.](#cbegin-2.sentence-1)
— *end note*]
### [25.3.5](#cend) ranges::cend [[range.access.cend]](range.access.cend)
[1](#cend-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L806)
The name ranges::cend denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#cend-1.sentence-1)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#cend-1.sentence-2)
Then:
- [(1.1)](#cend-1.1)
If E is an rvalue andenable_borrowed_range<remove_cv_t<T>> is false,ranges::cend(E) is ill-formed[.](#cend-1.1.sentence-1)
- [(1.2)](#cend-1.2)
Otherwise,
let U be ranges::end(*possibly-const-range*(t))[.](#cend-1.2.sentence-1)
ranges::cend(E) is expression-equivalent toconst_sentinel<decltype(U)>(U)[.](#cend-1.2.sentence-2)
[2](#cend-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L824)
[*Note [1](#cend-note-1)*:
Whenever ranges::cend(E) is a valid expression,
the types S and I of the expressionsranges::cend(E) and ranges::cbegin(E) model [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I>[.](#cend-2.sentence-1)
If S models [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]"),
then S also models *constant-iterator*[.](#cend-2.sentence-2)
— *end note*]
### [25.3.6](#rbegin) ranges::rbegin [[range.access.rbegin]](range.access.rbegin)
[1](#rbegin-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L837)
The name ranges::rbegin denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#rbegin-1.sentence-1)
[2](#rbegin-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L841)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#rbegin-2.sentence-1)
Then:
- [(2.1)](#rbegin-2.1)
If E is an rvalue and enable_borrowed_range<remove_cv_t<T>> is false, ranges::rbegin(E) is ill-formed[.](#rbegin-2.1.sentence-1)
- [(2.2)](#rbegin-2.2)
Otherwise, if T is an array type ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")) and remove_all_extents_t<T> is an incomplete type, ranges::rbegin(E) is ill-formed with no diagnostic required[.](#rbegin-2.2.sentence-1)
- [(2.3)](#rbegin-2.3)
Otherwise, if auto(t.rbegin()) is a valid expression 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]"), ranges::rbegin(E) is expression-equivalent to auto(t.rbegin())[.](#rbegin-2.3.sentence-1)
- [(2.4)](#rbegin-2.4)
Otherwise, if T is a class or enumeration type and auto(rbegin(t)) is a valid expression 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]") where the meaning of rbegin is established as-if by performing
argument-dependent lookup only ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")),
then ranges::rbegin(E) is expression-equivalent to
that expression[.](#rbegin-2.4.sentence-1)
- [(2.5)](#rbegin-2.5)
Otherwise, if both ranges::begin(t) and ranges::end(t) are valid expressions of the same type which models [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12Concept bidirectional_­iterator")), ranges::rbegin(E) is expression-equivalent to make_reverse_iterator(ranges::end(t))[.](#rbegin-2.5.sentence-1)
- [(2.6)](#rbegin-2.6)
Otherwise, ranges::rbegin(E) is ill-formed[.](#rbegin-2.6.sentence-1)
[3](#rbegin-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L884)
[*Note [1](#rbegin-note-1)*:
Diagnosable ill-formed cases above result in substitution failure
when ranges::rbegin(E) appears in the immediate context of a template instantiation[.](#rbegin-3.sentence-1)
— *end note*]
[4](#rbegin-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L891)
[*Note [2](#rbegin-note-2)*:
Whenever ranges::rbegin(E) is a valid expression, its 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]")[.](#rbegin-4.sentence-1)
— *end note*]
### [25.3.7](#rend) ranges::rend [[range.access.rend]](range.access.rend)
[1](#rend-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L900)
The name ranges::rend denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#rend-1.sentence-1)
[2](#rend-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L904)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#rend-2.sentence-1)
Then:
- [(2.1)](#rend-2.1)
If E is an rvalue and enable_borrowed_range<remove_cv_t<T>> is false, ranges::rend(E) is ill-formed[.](#rend-2.1.sentence-1)
- [(2.2)](#rend-2.2)
Otherwise, if T is an array type ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")) and remove_all_extents_t<T> is an incomplete type, ranges::rend(E) is ill-formed with no diagnostic required[.](#rend-2.2.sentence-1)
- [(2.3)](#rend-2.3)
Otherwise, if auto(t.rend()) is a valid expression whose type models [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<decltype(ranges::rbegin(E))> then ranges::rend(E) is expression-equivalent to auto(t.rend())[.](#rend-2.3.sentence-1)
- [(2.4)](#rend-2.4)
Otherwise, if T is a class or enumeration type and auto(rend(t)) is a valid expression whose type models [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<decltype(ranges::rbegin(E))> where the meaning of rend is established as-if by performing
argument-dependent lookup only ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")),
then ranges::rend(E) is expression-equivalent to
that expression[.](#rend-2.4.sentence-1)
- [(2.5)](#rend-2.5)
Otherwise, if both ranges::begin(t) and ranges::end(t) are valid expressions of the same type which models [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12Concept bidirectional_­iterator")),
then ranges::rend(E) is expression-equivalent to make_reverse_iterator(ranges::begin(t))[.](#rend-2.5.sentence-1)
- [(2.6)](#rend-2.6)
Otherwise, ranges::rend(E) is ill-formed[.](#rend-2.6.sentence-1)
[3](#rend-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L947)
[*Note [1](#rend-note-1)*:
Diagnosable ill-formed cases above
result in substitution failure when ranges::rend(E) appears in the immediate context of a template instantiation[.](#rend-3.sentence-1)
— *end note*]
[4](#rend-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L954)
[*Note [2](#rend-note-2)*:
Whenever ranges::rend(E) is a valid expression,
the types S and I of the expressionsranges::rend(E) and ranges::rbegin(E) model [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I>[.](#rend-4.sentence-1)
— *end note*]
### [25.3.8](#crbegin) ranges::crbegin [[range.access.crbegin]](range.access.crbegin)
[1](#crbegin-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L965)
The name ranges::crbegin denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#crbegin-1.sentence-1)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#crbegin-1.sentence-2)
Then:
- [(1.1)](#crbegin-1.1)
If E is an rvalue andenable_borrowed_range<remove_cv_t<T>> is false,ranges::crbegin(E) is ill-formed[.](#crbegin-1.1.sentence-1)
- [(1.2)](#crbegin-1.2)
Otherwise,
let U be ranges::rbegin(*possibly-const-range*(t))[.](#crbegin-1.2.sentence-1)
ranges::crbegin(E) is expression-equivalent toconst_iterator<decltype(U)>(U)[.](#crbegin-1.2.sentence-2)
[2](#crbegin-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L983)
[*Note [1](#crbegin-note-1)*:
Whenever ranges::crbegin(E) is a valid expression, its
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]") and[*constant-iterator*](const.iterators.alias#concept:constant-iterator "24.5.3.2Alias templates[const.iterators.alias]")[.](#crbegin-2.sentence-1)
— *end note*]
### [25.3.9](#crend) ranges::crend [[range.access.crend]](range.access.crend)
[1](#crend-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L993)
The name ranges::crend denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#crend-1.sentence-1)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#crend-1.sentence-2)
Then:
- [(1.1)](#crend-1.1)
If E is an rvalue andenable_borrowed_range<remove_cv_t<T>> is false,ranges::crend(E) is ill-formed[.](#crend-1.1.sentence-1)
- [(1.2)](#crend-1.2)
Otherwise,
let U be ranges::rend(*possibly-const-range*(t))[.](#crend-1.2.sentence-1)
ranges::crend(E) is expression-equivalent toconst_sentinel<decltype(U)>(U)[.](#crend-1.2.sentence-2)
[2](#crend-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1011)
[*Note [1](#crend-note-1)*:
Whenever ranges::crend(E) is a valid expression,
the types S and I of the expressionsranges::crend(E) and ranges::crbegin(E) model [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<S, I>[.](#crend-2.sentence-1)
If S models [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]"),
then S also models *constant-iterator*[.](#crend-2.sentence-2)
— *end note*]
### [25.3.10](#range.prim.size) ranges::size [[range.prim.size]](range.prim.size)
[1](#range.prim.size-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1024)
The name ranges::size denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#range.prim.size-1.sentence-1)
[2](#range.prim.size-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1028)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#range.prim.size-2.sentence-1)
Then:
- [(2.1)](#range.prim.size-2.1)
If T is an array of unknown bound ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")), ranges::size(E) is ill-formed[.](#range.prim.size-2.1.sentence-1)
- [(2.2)](#range.prim.size-2.2)
Otherwise, if T is an array type, ranges::size(E) is expression-equivalent to auto(extent_v<T>)[.](#range.prim.size-2.2.sentence-1)
- [(2.3)](#range.prim.size-2.3)
Otherwise, if disable_sized_range<remove_cv_t<T>> ([[range.sized]](range.sized "25.4.4Sized ranges"))
is false and auto(t.size()) is a valid expression of integer-like type ([[iterator.concept.winc]](iterator.concept.winc "24.3.4.4Concept weakly_­incrementable")), ranges::size(E) is expression-equivalent to auto(t.size())[.](#range.prim.size-2.3.sentence-1)
- [(2.4)](#range.prim.size-2.4)
Otherwise, if T is a class or enumeration type, disable_sized_range<remove_cv_t<T>> is false and auto(size(t)) is a valid expression of integer-like type
where the meaning of size is established as-if by performing
argument-dependent lookup only ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")),
then ranges::size(E) is expression-equivalent to
that expression[.](#range.prim.size-2.4.sentence-1)
- [(2.5)](#range.prim.size-2.5)
Otherwise, if *to-unsigned-like*(ranges::end(t) - ranges::begin(t)) ([[ranges.syn]](ranges.syn "25.2Header <ranges> synopsis"))
is a valid expression and
the types I and S of ranges::begin(t) and ranges::end(t) (respectively) model both [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I> ([[iterator.concept.sizedsentinel]](iterator.concept.sizedsentinel "24.3.4.8Concept sized_­sentinel_­for")) and [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]")<I>,
then ranges::size(E) is expression-equivalent to *to-unsigned-like*(ranges::end(t) - ranges::begin(t))[.](#range.prim.size-2.5.sentence-1)
- [(2.6)](#range.prim.size-2.6)
Otherwise, ranges::size(E) is ill-formed[.](#range.prim.size-2.6.sentence-1)
[3](#range.prim.size-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1075)
[*Note [1](#range.prim.size-note-1)*:
Diagnosable ill-formed cases above
result in substitution failure when ranges::size(E) appears in the immediate context of a template instantiation[.](#range.prim.size-3.sentence-1)
— *end note*]
[4](#range.prim.size-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1082)
[*Note [2](#range.prim.size-note-2)*:
Whenever ranges::size(E) is a valid expression, its
type is integer-like[.](#range.prim.size-4.sentence-1)
— *end note*]
### [25.3.11](#range.prim.ssize) ranges::ssize [[range.prim.ssize]](range.prim.ssize)
[1](#range.prim.ssize-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1091)
The name ranges::ssize denotes
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#range.prim.ssize-1.sentence-1)
[2](#range.prim.ssize-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1095)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#range.prim.ssize-2.sentence-1)
If ranges::size(t) is ill-formed,ranges::ssize(E) is ill-formed[.](#range.prim.ssize-2.sentence-2)
Otherwise let D be*make-signed-like-t*<decltype(ranges::size(t))>, orptrdiff_t if it is wider than that type;ranges::ssize(E) is expression-equivalent tostatic_cast<D>(ranges::size(t))[.](#range.prim.ssize-2.sentence-3)
### [25.3.12](#range.prim.size.hint) ranges::reserve_hint [[range.prim.size.hint]](range.prim.size.hint)
[1](#range.prim.size.hint-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1109)
The name ranges::reserve_hint denotes
a customization point object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#range.prim.size.hint-1.sentence-1)
[2](#range.prim.size.hint-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1113)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#range.prim.size.hint-2.sentence-1)
Then:
- [(2.1)](#range.prim.size.hint-2.1)
If ranges::size(E) is a valid expression,ranges::reserve_hint(E) is expression-equivalent toranges::size(E)[.](#range.prim.size.hint-2.1.sentence-1)
- [(2.2)](#range.prim.size.hint-2.2)
Otherwise,
if auto(t.reserve_hint()) is a valid expression of
integer-like type ([[iterator.concept.winc]](iterator.concept.winc "24.3.4.4Concept weakly_­incrementable")),ranges::reserve_hint(E) is expression-equivalent toauto(t.reserve_hint())[.](#range.prim.size.hint-2.2.sentence-1)
- [(2.3)](#range.prim.size.hint-2.3)
Otherwise,
if T is a class or enumeration type andauto(reserve_hint(t)) is a valid expression of
integer-like type where
the meaning of reserve_hint is established as-if by
performing argument-dependent lookup only ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4Argument-dependent name lookup")), thenranges::reserve_hint(E) is expression-equivalent to that expression[.](#range.prim.size.hint-2.3.sentence-1)
- [(2.4)](#range.prim.size.hint-2.4)
Otherwise,ranges::reserve_hint(E) is ill-formed[.](#range.prim.size.hint-2.4.sentence-1)
[*Note [1](#range.prim.size.hint-note-1)*:
Diagnosable ill-formed cases above result in substitution failure whenranges::reserve_hint(E) appears in the immediate context of
a template instantiation[.](#range.prim.size.hint-2.sentence-3)
— *end note*]
[*Note [2](#range.prim.size.hint-note-2)*:
Whenever ranges::reserve_hint(E) is a valid expression,
its type is integer-like[.](#range.prim.size.hint-2.sentence-4)
— *end note*]
### [25.3.13](#range.prim.empty) ranges::empty [[range.prim.empty]](range.prim.empty)
[1](#range.prim.empty-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1153)
The name ranges::empty denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#range.prim.empty-1.sentence-1)
[2](#range.prim.empty-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1157)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#range.prim.empty-2.sentence-1)
Then:
- [(2.1)](#range.prim.empty-2.1)
If T is an array of unknown bound ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")), ranges::empty(E) is ill-formed[.](#range.prim.empty-2.1.sentence-1)
- [(2.2)](#range.prim.empty-2.2)
Otherwise, if bool(t.empty()) is a valid expression, ranges::empty(E) is expression-equivalent to bool(t.empty())[.](#range.prim.empty-2.2.sentence-1)
- [(2.3)](#range.prim.empty-2.3)
Otherwise, if (ranges::size(t) == 0) is a valid expression, ranges::empty(E) is expression-equivalent to (ranges::size(t) == 0)[.](#range.prim.empty-2.3.sentence-1)
- [(2.4)](#range.prim.empty-2.4)
Otherwise, if bool(ranges::begin(t) == ranges::end(t)) is a valid expression and
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::empty(E) is expression-equivalent to bool(ranges::begin(t) == ranges::end(t))[.](#range.prim.empty-2.4.sentence-1)
- [(2.5)](#range.prim.empty-2.5)
Otherwise, ranges::empty(E) is ill-formed[.](#range.prim.empty-2.5.sentence-1)
[3](#range.prim.empty-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1187)
[*Note [1](#range.prim.empty-note-1)*:
Diagnosable ill-formed cases above
result in substitution failure when ranges::empty(E) appears in the immediate context of a template instantiation[.](#range.prim.empty-3.sentence-1)
— *end note*]
[4](#range.prim.empty-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1194)
[*Note [2](#range.prim.empty-note-2)*:
Whenever ranges::empty(E) is a valid expression,
it has type bool[.](#range.prim.empty-4.sentence-1)
— *end note*]
### [25.3.14](#range.prim.data) ranges::data [[range.prim.data]](range.prim.data)
[1](#range.prim.data-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1203)
The name ranges::data denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#range.prim.data-1.sentence-1)
[2](#range.prim.data-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1207)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#range.prim.data-2.sentence-1)
Then:
- [(2.1)](#range.prim.data-2.1)
If E is an rvalue and enable_borrowed_range<remove_cv_t<T>> is false, ranges::data(E) is ill-formed[.](#range.prim.data-2.1.sentence-1)
- [(2.2)](#range.prim.data-2.2)
Otherwise, if T is an array type ([[dcl.array]](dcl.array#term.array.type "9.3.4.5Arrays")) and remove_all_extents_t<T> is an incomplete type, ranges::data(E) is ill-formed with no diagnostic required[.](#range.prim.data-2.2.sentence-1)
- [(2.3)](#range.prim.data-2.3)
Otherwise, if auto(t.data()) is a valid expression of pointer to object type, ranges::data(E) is expression-equivalent to auto(t.data())[.](#range.prim.data-2.3.sentence-1)
- [(2.4)](#range.prim.data-2.4)
Otherwise, if ranges::begin(t) is a valid expression whose type models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]"), ranges::data(E) is expression-equivalent to to_address(ranges::begin(t))[.](#range.prim.data-2.4.sentence-1)
- [(2.5)](#range.prim.data-2.5)
Otherwise, ranges::data(E) is ill-formed[.](#range.prim.data-2.5.sentence-1)
[3](#range.prim.data-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1239)
[*Note [1](#range.prim.data-note-1)*:
Diagnosable ill-formed cases above
result in substitution failure when ranges::data(E) appears in the immediate context of a template instantiation[.](#range.prim.data-3.sentence-1)
— *end note*]
[4](#range.prim.data-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1246)
[*Note [2](#range.prim.data-note-2)*:
Whenever ranges::data(E) is a valid expression, it
has pointer to object type[.](#range.prim.data-4.sentence-1)
— *end note*]
### [25.3.15](#range.prim.cdata) ranges::cdata [[range.prim.cdata]](range.prim.cdata)
template<class T>constexpr auto *as-const-pointer*(const T* p) noexcept { return p; } // *exposition only*
[1](#range.prim.cdata-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1260)
The name ranges::cdata denotes a customization point
object ([[customization.point.object]](customization.point.object "16.3.3.3.5Customization Point Object types"))[.](#range.prim.cdata-1.sentence-1)
Given a subexpression E with type T,
let t be an lvalue that denotes the reified object for E[.](#range.prim.cdata-1.sentence-2)
Then:
- [(1.1)](#range.prim.cdata-1.1)
If E is an rvalue andenable_borrowed_range<remove_cv_t<T>> is false,ranges::cdata(E) is ill-formed[.](#range.prim.cdata-1.1.sentence-1)
- [(1.2)](#range.prim.cdata-1.2)
Otherwise,ranges::cdata(E) is expression-equivalent to*as-const-pointer*(ranges::data(*possibly-const-range*(t)))[.](#range.prim.cdata-1.2.sentence-1)
[2](#range.prim.cdata-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L1277)
[*Note [1](#range.prim.cdata-note-1)*:
Whenever ranges::cdata(E) is a valid expression, it
has pointer to constant object type[.](#range.prim.cdata-2.sentence-1)
— *end note*]