24 Ranges library [ranges]

24.3 Range access [range.access]

In addition to being available via inclusion of the <ranges> header, the customization point objects in [range.access] are available when <iterator> ([iterator.synopsis]) is included.

24.3.1 ranges​::​begin [range.access.begin]

The name ranges​::​begin denotes a customization point object ([customization.point.object]).
Given a subexpression E and an lvalue t that denotes the same object as E, if E is an rvalue and enable_­safe_­range<remove_­cvref_­t<decltype((E))>> is false, ranges​::​begin(E) is ill-formed.
Otherwise, ranges​::​begin(E) is expression-equivalent to:
  • t + 0 if t is of array type ([basic.compound]).
  • Otherwise, decay-copy(t.begin()) if it is a valid expression and its type I models input_­or_­output_­iterator.
  • Otherwise, decay-copy(begin(t)) if it is a valid expression and its type I models input_­or_­output_­iterator with overload resolution performed in a context that includes the declarations:
    template<class T> void begin(T&&) = delete;
    template<class T> void begin(initializer_list<T>&&) = delete;
      
    and does not include a declaration of ranges​::​begin.
  • Otherwise, ranges​::​begin(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​begin(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​begin(E) is a valid expression, its type models input_­or_­output_­iterator.
— end note
 ]

24.3.2 ranges​::​end [range.access.end]

The name ranges​::​end denotes a customization point object ([customization.point.object]).
Given a subexpression E and an lvalue t that denotes the same object as E, if E is an rvalue and enable_­safe_­range<remove_­cvref_­t<decltype((E))>> is false, ranges​::​end(E) is ill-formed.
Otherwise, ranges​::​end(E) is expression-equivalent to:
  • t + extent_­v<T> if E is of array type ([basic.compound]) T.
  • Otherwise, decay-copy(t.end()) if it is a valid expression and its type S models
    sentinel_for<decltype(ranges::begin(E))>
      
  • Otherwise, decay-copy(end(t)) if it is a valid expression and its type S models
    sentinel_for<decltype(ranges::begin(E))>
      
    with overload resolution performed in a context that includes the declarations:
    template<class T> void end(T&&) = delete;
    template<class T> void end(initializer_list<T>&&) = delete;
      
    and does not include a declaration of ranges​::​end.
  • Otherwise, ranges​::​end(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​end(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​end(E) is a valid expression, the types S and I of ranges​::​end(E) and ranges​::​begin(E) model sentinel_­for<S, I>.
— end note
 ]

24.3.3 ranges​::​cbegin [range.access.cbegin]

The name ranges​::​cbegin denotes a customization point object.
The expression ranges​::​​cbegin(E) for some subexpression E of type T is expression-equivalent to:
  • ranges​::​begin(static_­cast<const T&>(E)) if E is an lvalue.
  • Otherwise, ranges​::​begin(static_­cast<const T&&>(E)).
Note
:
Whenever ranges​::​cbegin(E) is a valid expression, its type models input_­or_­output_­iterator.
— end note
 ]

24.3.4 ranges​::​cend [range.access.cend]

The name ranges​::​cend denotes a customization point object.
The expression ranges​::​cend(E) for some subexpression E of type T is expression-equivalent to:
  • ranges​::​end(static_­cast<const T&>(E)) if E is an lvalue.
  • Otherwise, ranges​::​end(static_­cast<const T&&>(E)).
Note
:
Whenever ranges​::​cend(E) is a valid expression, the types S and I of ranges​::​cend(E) and ranges​::​cbegin(E) model sentinel_­for<S, I>.
— end note
 ]

24.3.5 ranges​::​rbegin [range.access.rbegin]

The name ranges​::​rbegin denotes a customization point object ([customization.point.object]).
Given a subexpression E and an lvalue t that denotes the same object as E, if E is an rvalue and enable_­safe_­range<remove_­cvref_­t<decltype((E))>> is false, ranges​::​rbegin(E) is ill-formed.
Otherwise, ranges​::​rbegin(E) is expression-equivalent to:
  • decay-copy(t.rbegin()) if it is a valid expression and its type I models input_­or_­output_­iterator.
  • Otherwise, decay-copy(rbegin(t)) if it is a valid expression and its type I models input_­or_­output_­iterator with overload resolution performed in a context that includes the declaration:
    template<class T> void rbegin(T&&) = delete;
      
    and does not include a declaration of ranges​::​rbegin.
  • Otherwise, make_­reverse_­iterator(ranges​::​end(t)) if both ranges​::​begin(t) and ranges​::​end(​t) are valid expressions of the same type I which models bidirectional_­iterator ([iterator.concept.bidir]).
  • Otherwise, ranges​::​rbegin(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​rbegin(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​rbegin(E) is a valid expression, its type models input_­or_­output_­iterator.
— end note
 ]

24.3.6 ranges​::​rend [range.access.rend]

The name ranges​::​rend denotes a customization point object ([customization.point.object]).
Given a subexpression E and an lvalue t that denotes the same object as E, if E is an rvalue and enable_­safe_­range<remove_­cvref_­t<decltype((E))>> is false, ranges​::​rend(E) is ill-formed.
Otherwise, ranges​::​rend(E) is expression-equivalent to:
  • decay-copy(t.rend()) if it is a valid expression and its type S models
    sentinel_for<decltype(ranges::rbegin(E))>
      
  • Otherwise, decay-copy(rend(t)) if it is a valid expression and its type S models
    sentinel_for<decltype(ranges::rbegin(E))>
      
    with overload resolution performed in a context that includes the declaration:
    template<class T> void rend(T&&) = delete;
      
    and does not include a declaration of ranges​::​rend.
  • Otherwise, make_­reverse_­iterator(ranges​::​begin(t)) if both ranges​::​begin(t) and ranges​::​​end(t) are valid expressions of the same type I which models bidirectional_­iterator ([iterator.concept.bidir]).
  • Otherwise, ranges​::​rend(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​rend(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​rend(E) is a valid expression, the types S and I of ranges​::​rend(E) and ranges​::​rbegin(E) model sentinel_­for<S, I>.
— end note
 ]

24.3.7 ranges​::​crbegin [range.access.crbegin]

The name ranges​::​crbegin denotes a customization point object.
The expression ranges​::​​crbegin(E) for some subexpression E of type T is expression-equivalent to:
  • ranges​::​​rbegin(static_­cast<const T&>(E)) if E is an lvalue.
  • Otherwise, ranges​::​rbegin(static_­cast<const T&&>(E)).
Note
:
Whenever ranges​::​crbegin(E) is a valid expression, its type models input_­or_­output_­iterator.
— end note
 ]

24.3.8 ranges​::​crend [range.access.crend]

The name ranges​::​crend denotes a customization point object.
The expression ranges​::​​crend(E) for some subexpression E of type T is expression-equivalent to:
  • ranges​::​rend(static_­cast<const T&>(E)) if E is an lvalue.
  • Otherwise, ranges​::​rend(static_­cast<const T&&>(E)).
Note
:
Whenever ranges​::​crend(E) is a valid expression, the types S and I of ranges​::​crend(E) and ranges​::​crbegin(E) model sentinel_­for<S, I>.
— end note
 ]

24.3.9 ranges​::​size [range.prim.size]

The name size denotes a customization point object.
The expression ranges​::​size(E) for some subexpression E with type T is expression-equivalent to:
  • decay-copy(extent_­v<T>) if T is an array type ([basic.compound]).
  • Otherwise, if disable_­sized_­range<remove_­cv_­t<T>> ([range.sized]) is false:
    • decay-copy(E.size()) if it is a valid expression and its type I is integer-like ([iterator.concept.winc]).
    • Otherwise, decay-copy(size(E)) if it is a valid expression and its type I is integer-like with overload resolution performed in a context that includes the declaration:
      template<class T> void size(T&&) = delete;
          
      and does not include a declaration of ranges​::​size.
  • Otherwise, make-unsigned-like(ranges​::​end(E) - ranges​::​begin(E)) ([range.subrange]) if it is a valid expression and the types I and S of ranges​::​begin(E) and ranges​::​end(E) (respectively) model both sized_­sentinel_­for<S, I> ([iterator.concept.sizedsentinel]) and forward_­iterator<I>. However, E is evaluated only once.
  • Otherwise, ranges​::​size(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​size(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​size(E) is a valid expression, its type is integer-like.
— end note
 ]

24.3.10 ranges​::​empty [range.prim.empty]

The name empty denotes a customization point object.
The expression ranges​::​empty(E) for some subexpression E is expression-equivalent to:
  • bool((E).empty()) if it is a valid expression.
  • Otherwise, (ranges​::​size(E) == 0) if it is a valid expression.
  • Otherwise, EQ, where EQ is bool(ranges​::​begin(E) == ranges​::​end(E)) except that E is only evaluated once, if EQ is a valid expression and the type of ranges​::​begin(E) models forward_­iterator.
  • Otherwise, ranges​::​empty(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​empty(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​empty(E) is a valid expression, it has type bool.
— end note
 ]

24.3.11 ranges​::​data [range.prim.data]

The name data denotes a customization point object.
The expression ranges​::​data(E) for some subexpression E is expression-equivalent to:
  • If E is an lvalue, decay-copy(E.data()) if it is a valid expression of pointer to object type.
  • Otherwise, if ranges​::​begin(E) is a valid expression whose type models contiguous_­iterator, to_­address(ranges​::​begin(E)).
  • Otherwise, ranges​::​data(E) is ill-formed.
    Note
    : This case can result in substitution failure when ranges​::​data(E) appears in the immediate context of a template instantiation. — end note
     ]
Note
:
Whenever ranges​::​data(E) is a valid expression, it has pointer to object type.
— end note
 ]

24.3.12 ranges​::​cdata [range.prim.cdata]

The name cdata denotes a customization point object.
The expression ranges​::​cdata(E) for some subexpression E of type T is expression-equivalent to:
  • ranges​::​data(static_­cast<const T&>(E)) if E is an lvalue.
  • Otherwise, ranges​::​data(static_­cast<const T&&>(E)).
Note
:
Whenever ranges​::​cdata(E) is a valid expression, it has pointer to object type.
— end note
 ]