[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.2 Header <ranges> synopsis [ranges.syn]") header, the customization point objects in [range.access] are
available when the header [<iterator>](iterator.synopsis#header:%3citerator%3e "24.2 Header <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.1 General [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.5 Temporary 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.5 Customization 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.5 Arrays")) 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.6 Concept 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.6 Concept 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.4 Argument-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.6 Concept 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.5 Customization 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.5 Arrays")) 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.7 Concept 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.7 Concept 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.4 Argument-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.7 Concept 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.5 Customization 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.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") and [*constant-iterator*](const.iterators.alias#concept:constant-iterator "24.5.3.2 Alias 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.5 Customization 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.7 Concept 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.9 Concept 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.5 Customization 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.5 Arrays")) 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.6 Concept 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.6 Concept 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.4 Argument-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.12 Concept bidirectional_­iterator [iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12 Concept 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.6 Concept 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.5 Customization 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.5 Arrays")) 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.7 Concept 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.7 Concept 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.4 Argument-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.12 Concept bidirectional_­iterator [iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12 Concept 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.7 Concept 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.5 Customization 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.6 Concept input_­or_­output_­iterator [iterator.concept.iterator]") and[*constant-iterator*](const.iterators.alias#concept:constant-iterator "24.5.3.2 Alias 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.5 Customization 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.7 Concept 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.9 Concept 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.5 Customization 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.5 Arrays")), 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.4 Sized ranges"))
 is false and auto(t.size()) is a valid expression of integer-like type ([[iterator.concept.winc]](iterator.concept.winc "24.3.4.4 Concept 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.4 Argument-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.2 Header <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.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")<S, I> ([[iterator.concept.sizedsentinel]](iterator.concept.sizedsentinel "24.3.4.8 Concept sized_­sentinel_­for")) and [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept 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.5 Customization 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.5 Customization 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.4 Concept 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.4 Argument-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.5 Customization 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.5 Arrays")), 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.11 Concept 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.5 Customization 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.5 Arrays")) 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.14 Concept 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.5 Customization 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*]
