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

33 KiB
Raw Permalink Blame History

[range.access]

25 Ranges library [ranges]

25.3 Range access [range.access]

25.3.1 General [range.access.general]

1

#

In addition to being available via inclusion of the header, the customization point objects in [range.access] are available when the header is included.

2

#

Within [range.access], the reified object of a subexpression E denotes

the same object as E if E is a glvalue, or

the result of applying the temporary materialization conversion ([conv.rval]) to E otherwise.

25.3.2 ranges::begin [range.access.begin]

1

#

The name ranges::begin denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If E is an rvalue and enable_borrowed_range<remove_cv_t> is false, ranges::begin(E) is ill-formed.

  • (2.2)

    Otherwise, if T is an array type ([dcl.array]) and remove_all_extents_t is an incomplete type, ranges::begin(E) is ill-formed with no diagnostic required.

  • (2.3)

    Otherwise, if T is an array type, ranges::begin(E) is expression-equivalent to t + 0.

  • (2.4)

    Otherwise, if auto(t.begin()) is a valid expression whose type models input_or_output_iterator, ranges::begin(E) is expression-equivalent to auto(t.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 where the meaning of begin is established as-if by performing argument-dependent lookup only ([basic.lookup.argdep]), then ranges::begin(E) is expression-equivalent to that expression.

  • (2.6)

    Otherwise, ranges::begin(E) is ill-formed.

3

#

[Note 1:

Diagnosable ill-formed cases above result in substitution failure when ranges::begin(E) appears in the immediate context of a template instantiation.

— end note]

4

#

[Note 2:

Whenever ranges::begin(E) is a valid expression, its type modelsinput_or_output_iterator.

— end note]

25.3.3 ranges::end [range.access.end]

1

#

The name ranges::end denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If E is an rvalue and enable_borrowed_range<remove_cv_t> is false, ranges::end(E) is ill-formed.

  • (2.2)

    Otherwise, if T is an array type ([dcl.array]) and remove_all_extents_t is an incomplete type, ranges::end(E) is ill-formed with no diagnostic required.

  • (2.3)

    Otherwise, if T is an array of unknown bound, ranges::end(E) is ill-formed.

  • (2.4)

    Otherwise, if T is an array, ranges::end(E) is expression-equivalent to t + extent_v.

  • (2.5)

    Otherwise, if auto(t.end()) is a valid expression whose type models sentinel_for<iterator_t> then ranges::end(E) is expression-equivalent to auto(t.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_t> where the meaning of end is established as-if by performing argument-dependent lookup only ([basic.lookup.argdep]), then ranges::end(E) is expression-equivalent to that expression.

  • (2.7)

    Otherwise, ranges::end(E) is ill-formed.

3

#

[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 note]

4

#

[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<S, I>.

— end note]

25.3.4 ranges::cbegin [range.access.cbegin]

1

#

The name ranges::cbegin denotes a customization point object ([customization.point.object]).

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (1.1)

    If E is an rvalue andenable_borrowed_range<remove_cv_t> is false,ranges::cbegin(E) is ill-formed.

  • (1.2)

    Otherwise, let U be ranges::begin(possibly-const-range(t)). ranges::cbegin(E) is expression-equivalent toconst_iterator<decltype(U)>(U).

2

#

[Note 1:

Whenever ranges::cbegin(E) is a valid expression, its type modelsinput_or_output_iterator and constant-iterator.

— end note]

25.3.5 ranges::cend [range.access.cend]

1

#

The name ranges::cend denotes a customization point object ([customization.point.object]).

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (1.1)

    If E is an rvalue andenable_borrowed_range<remove_cv_t> is false,ranges::cend(E) is ill-formed.

  • (1.2)

    Otherwise, let U be ranges::end(possibly-const-range(t)). ranges::cend(E) is expression-equivalent toconst_sentinel<decltype(U)>(U).

2

#

[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<S, I>.

If S models input_iterator, then S also models constant-iterator.

— end note]

25.3.6 ranges::rbegin [range.access.rbegin]

1

#

The name ranges::rbegin denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If E is an rvalue and enable_borrowed_range<remove_cv_t> is false, ranges::rbegin(E) is ill-formed.

  • (2.2)

    Otherwise, if T is an array type ([dcl.array]) and remove_all_extents_t is an incomplete type, ranges::rbegin(E) is ill-formed with no diagnostic required.

  • (2.3)

    Otherwise, if auto(t.rbegin()) is a valid expression whose type models input_or_output_iterator, ranges::rbegin(E) is expression-equivalent to auto(t.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 where the meaning of rbegin is established as-if by performing argument-dependent lookup only ([basic.lookup.argdep]), then ranges::rbegin(E) is expression-equivalent to that expression.

  • (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]), ranges::rbegin(E) is expression-equivalent to make_reverse_iterator(ranges::end(t)).

  • (2.6)

    Otherwise, ranges::rbegin(E) is ill-formed.

3

#

[Note 1:

Diagnosable ill-formed cases above result in substitution failure when ranges::rbegin(E) appears in the immediate context of a template instantiation.

— end note]

4

#

[Note 2:

Whenever ranges::rbegin(E) is a valid expression, its type modelsinput_or_output_iterator.

— end note]

25.3.7 ranges::rend [range.access.rend]

1

#

The name ranges::rend denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If E is an rvalue and enable_borrowed_range<remove_cv_t> is false, ranges::rend(E) is ill-formed.

  • (2.2)

    Otherwise, if T is an array type ([dcl.array]) and remove_all_extents_t is an incomplete type, ranges::rend(E) is ill-formed with no diagnostic required.

  • (2.3)

    Otherwise, if auto(t.rend()) is a valid expression whose type models sentinel_for<decltype(ranges::rbegin(E))> then ranges::rend(E) is expression-equivalent to auto(t.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<decltype(ranges::rbegin(E))> where the meaning of rend is established as-if by performing argument-dependent lookup only ([basic.lookup.argdep]), then ranges::rend(E) is expression-equivalent to that expression.

  • (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]), then ranges::rend(E) is expression-equivalent to make_reverse_iterator(ranges::begin(t)).

  • (2.6)

    Otherwise, ranges::rend(E) is ill-formed.

3

#

[Note 1:

Diagnosable ill-formed cases above result in substitution failure when ranges::rend(E) appears in the immediate context of a template instantiation.

— end note]

4

#

[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<S, I>.

— end note]

25.3.8 ranges::crbegin [range.access.crbegin]

1

#

The name ranges::crbegin denotes a customization point object ([customization.point.object]).

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (1.1)

    If E is an rvalue andenable_borrowed_range<remove_cv_t> is false,ranges::crbegin(E) is ill-formed.

  • (1.2)

    Otherwise, let U be ranges::rbegin(possibly-const-range(t)). ranges::crbegin(E) is expression-equivalent toconst_iterator<decltype(U)>(U).

2

#

[Note 1:

Whenever ranges::crbegin(E) is a valid expression, its type models input_or_output_iterator andconstant-iterator.

— end note]

25.3.9 ranges::crend [range.access.crend]

1

#

The name ranges::crend denotes a customization point object ([customization.point.object]).

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (1.1)

    If E is an rvalue andenable_borrowed_range<remove_cv_t> is false,ranges::crend(E) is ill-formed.

  • (1.2)

    Otherwise, let U be ranges::rend(possibly-const-range(t)). ranges::crend(E) is expression-equivalent toconst_sentinel<decltype(U)>(U).

2

#

[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<S, I>.

If S models input_iterator, then S also models constant-iterator.

— end note]

25.3.10 ranges::size [range.prim.size]

1

#

The name ranges::size denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If T is an array of unknown bound ([dcl.array]), ranges::size(E) is ill-formed.

  • (2.2)

    Otherwise, if T is an array type, ranges::size(E) is expression-equivalent to auto(extent_v).

  • (2.3)

    Otherwise, if disable_sized_range<remove_cv_t> ([range.sized]) is false and auto(t.size()) is a valid expression of integer-like type ([iterator.concept.winc]), ranges::size(E) is expression-equivalent to auto(t.size()).

  • (2.4)

    Otherwise, if T is a class or enumeration type, disable_sized_range<remove_cv_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]), then ranges::size(E) is expression-equivalent to that expression.

  • (2.5)

    Otherwise, if to-unsigned-like(ranges::end(t) - ranges::begin(t)) ([ranges.syn]) is a valid expression and the types I and S of ranges::begin(t) and ranges::end(t) (respectively) model both sized_sentinel_for<S, I> ([iterator.concept.sizedsentinel]) and forward_iterator, then ranges::size(E) is expression-equivalent to to-unsigned-like(ranges::end(t) - ranges::begin(t)).

  • (2.6)

    Otherwise, ranges::size(E) is ill-formed.

3

#

[Note 1:

Diagnosable ill-formed cases above result in substitution failure when ranges::size(E) appears in the immediate context of a template instantiation.

— end note]

4

#

[Note 2:

Whenever ranges::size(E) is a valid expression, its type is integer-like.

— end note]

25.3.11 ranges::ssize [range.prim.ssize]

1

#

The name ranges::ssize denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

If ranges::size(t) is ill-formed,ranges::ssize(E) is ill-formed.

Otherwise let D bemake-signed-like-t<decltype(ranges::size(t))>, orptrdiff_t if it is wider than that type;ranges::ssize(E) is expression-equivalent tostatic_cast(ranges::size(t)).

25.3.12 ranges::reserve_hint [range.prim.size.hint]

1

#

The name ranges::reserve_hint denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If ranges::size(E) is a valid expression,ranges::reserve_hint(E) is expression-equivalent toranges::size(E).

  • (2.2)

    Otherwise, if auto(t.reserve_hint()) is a valid expression of integer-like type ([iterator.concept.winc]),ranges::reserve_hint(E) is expression-equivalent toauto(t.reserve_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]), thenranges::reserve_hint(E) is expression-equivalent to that expression.

  • (2.4)

    Otherwise,ranges::reserve_hint(E) is ill-formed.

[Note 1:

Diagnosable ill-formed cases above result in substitution failure whenranges::reserve_hint(E) appears in the immediate context of a template instantiation.

— end note]

[Note 2:

Whenever ranges::reserve_hint(E) is a valid expression, its type is integer-like.

— end note]

25.3.13 ranges::empty [range.prim.empty]

1

#

The name ranges::empty denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If T is an array of unknown bound ([dcl.array]), ranges::empty(E) is ill-formed.

  • (2.2)

    Otherwise, if bool(t.empty()) is a valid expression, ranges::empty(E) is expression-equivalent to bool(t.empty()).

  • (2.3)

    Otherwise, if (ranges::size(t) == 0) is a valid expression, ranges::empty(E) is expression-equivalent to (ranges::size(t) == 0).

  • (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, ranges::empty(E) is expression-equivalent to bool(ranges::begin(t) == ranges::end(t)).

  • (2.5)

    Otherwise, ranges::empty(E) is ill-formed.

3

#

[Note 1:

Diagnosable ill-formed cases above result in substitution failure when ranges::empty(E) appears in the immediate context of a template instantiation.

— end note]

4

#

[Note 2:

Whenever ranges::empty(E) is a valid expression, it has type bool.

— end note]

25.3.14 ranges::data [range.prim.data]

1

#

The name ranges::data denotes a customization point object ([customization.point.object]).

2

#

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (2.1)

    If E is an rvalue and enable_borrowed_range<remove_cv_t> is false, ranges::data(E) is ill-formed.

  • (2.2)

    Otherwise, if T is an array type ([dcl.array]) and remove_all_extents_t is an incomplete type, ranges::data(E) is ill-formed with no diagnostic required.

  • (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()).

  • (2.4)

    Otherwise, if ranges::begin(t) is a valid expression whose type models contiguous_iterator, ranges::data(E) is expression-equivalent to to_address(ranges::begin(t)).

  • (2.5)

    Otherwise, ranges::data(E) is ill-formed.

3

#

[Note 1:

Diagnosable ill-formed cases above result in substitution failure when ranges::data(E) appears in the immediate context of a template instantiation.

— end note]

4

#

[Note 2:

Whenever ranges::data(E) is a valid expression, it has pointer to object type.

— end note]

25.3.15 ranges::cdata [range.prim.cdata]

templateconstexpr auto as-const-pointer(const T* p) noexcept { return p; } // exposition only

1

#

The name ranges::cdata denotes a customization point object ([customization.point.object]).

Given a subexpression E with type T, let t be an lvalue that denotes the reified object for E.

Then:

  • (1.1)

    If E is an rvalue andenable_borrowed_range<remove_cv_t> is false,ranges::cdata(E) is ill-formed.

  • (1.2)

    Otherwise,ranges::cdata(E) is expression-equivalent toas-const-pointer(ranges::data(possibly-const-range(t))).

2

#

[Note 1:

Whenever ranges::cdata(E) is a valid expression, it has pointer to constant object type.

— end note]