10 Ranges library [ranges]

10.5 Range primitives [range.primitives]

In addition to being available via inclusion of the <experimental/ranges/range> header, the customization point objects in [range.primitives] are available when <experimental/ranges/iterator> is included.

10.5.1 size [range.primitives.size]

The name size denotes a customization point object ([customization.point.object]). The expression ranges::size(E) for some subexpression E with type T is expression-equivalent to:

  • DECAY_COPY(extent<T>::value) if T is an array type ( ISO/IEC 14882:2014 §[basic.compound]).

  • Otherwise, DECAY_COPY(static_cast<const T&>(E).size()) if it is a valid expression and its type I satisfies Integral<I> and disable_sized_range<T> ([ranges.sized]) is false.

  • Otherwise, DECAY_COPY(size(static_cast<const T&>(E))) if it is a valid expression and its type I satisfies Integral<I> with overload resolution performed in a context that includes the declaration void size(const auto&) = delete; and does not include a declaration of ranges::size, and disable_sized_range<T> is false.

  • Otherwise, DECAY_COPY(ranges::cend(E) - ranges::cbegin(E)), except that E is only evaluated once, if it is a valid expression and the types I and S of ranges::cbegin(E) and ranges::cend(E) meet the syntactic requirements of SizedSentinel<S, I> ([iterators.sizedsentinel]) and ForwardIterator<I>. If SizedSentinel and ForwardIterator are not satisfied, the program is ill-formed with no diagnostic required.

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

Note: Whenever ranges::size(E) is a valid expression, its type satisfies Integral.  — end note ]

10.5.2 empty [range.primitives.empty]

The name empty denotes a customization point object ([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, bool(ranges::begin(E) == ranges::end(E)), except that E is only evaluated once, if it is a valid expression and the type of ranges::begin(E) satisfies ForwardIterator.

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

Note: Whenever ranges::empty(E) is a valid expression, it has type bool.  — end note ]

10.5.3 data [range.primitives.data]

The name data denotes a customization point object ([customization.point.object]). The expression ranges::data(E) for some subexpression E is expression-equivalent to:

  • ranges::data(static_cast<const T&>(E)) if E is an rvalue of type T. This usage is deprecated. [ Note: This deprecated usage exists so that ranges::data(E) behaves similarly to std::data(E) as defined in the C++ Working Paper when E is an rvalue.  — end note ]

  • Otherwise, DECAY_COPY((E).data()) if it is a valid expression of pointer to object type.

  • Otherwise, ranges::begin(E) if it is a valid expression of pointer to object type.

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

Note: Whenever ranges::data(E) is a valid expression, it has pointer to object type.  — end note ]

10.5.4 cdata [range.primitives.cdata]

The name cdata denotes a customization point object ([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)).

Use of ranges::cdata(E) with rvalue E is deprecated. [ Note: This deprecated usage exists so that ranges::cdata(E) has behavior consistent with ranges::data(E) when E is an rvalue.  — end note ]

Note: Whenever ranges::cdata(E) is a valid expression, it has pointer to object type.  — end note ]