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

24.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
]

24.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
]

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

24.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
]

24.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
]

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 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<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 models Integral.
    • Otherwise, decay-copy(size(E)) if it is a valid expression and its type I models Integral 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, (ranges::end(E) - ranges::begin(E)) if it is a valid expression and the types I and S of ranges::begin(E) and ranges::end(E) model SizedSentinel<S, I> ([iterator.concept.sizedsentinel]) and ForwardIterator<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 models Integral.
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 ForwardIterator.
  • 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 ContiguousIterator,
    ranges::begin(E) == ranges::end(E) ? nullptr : addressof(*ranges::begin(E))
      
    except that E is evaluated only once.
  • 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
]