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

The expression
ranges::size(E) for some subexpression E with type
T is expression-equivalent to:

- Otherwise, if disable_sized_range<remove_cv_t<T>> ([range.sized]) is false:
- 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.

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.

The expression
ranges::data(E) for some subexpression E is
expression-equivalent to: