23 Ranges library [ranges]

23.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> is included.

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

The name ranges::begin denotes a customization point object.
The expression ranges::​begin(E) for some subexpression E is expression-equivalent to:
  • E + 0 if E is an lvalue of array type ([basic.compound]).
  • Otherwise, if E is an lvalue, decay-copy(E.begin()) if it is a valid expression and its type I models Iterator.
  • Otherwise, decay-copy(begin(E)) if it is a valid expression and its type I models 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 Iterator.
end note
]

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

The name ranges::end denotes a customization point object.
The expression ranges::end(E) for some subexpression E is expression-equivalent to:
  • E + extent_­v<T> if E is an lvalue of array type ([basic.compound]) T.
  • Otherwise, if E is an lvalue, decay-copy(E.end()) if it is a valid expression and its type S models Sentinel<decltype(​ranges::​begin(E))>.
  • Otherwise, decay-copy(end(E)) if it is a valid expression and its type S models Sentinel<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<S, I>.
end note
]

23.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 Iterator.
end note
]

23.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<S, I>.
end note
]

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

The name ranges::rbegin denotes a customization point object.
The expression ranges::​rbegin(E) for some subexpression E is expression-equivalent to:
  • If E is an lvalue, decay-copy(E.rbegin()) if it is a valid expression and its type I models Iterator.
  • Otherwise, decay-copy(rbegin(E)) if it is a valid expression and its type I models 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(E)) if both ranges::begin(E) and ranges::end(​E) are valid expressions of the same type I which models BidirectionalIterator.
  • 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 Iterator.
end note
]

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

The name ranges::rend denotes a customization point object.
The expression ranges::rend(E) for some subexpression E is expression-equivalent to:
  • If E is an lvalue, decay-copy(E.rend()) if it is a valid expression and its type S models Sentinel<decltype(ranges::rbegin(E))>.
  • Otherwise, decay-copy(rend(E)) if it is a valid expression and its type S models Sentinel<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(E)) if both ranges::begin(E) and ranges::​end(E) are valid expressions of the same type I which models BidirectionalIterator.
  • 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<S, I>.
end note
]

23.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 Iterator.
end note
]

23.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<S, I>.
end note
]