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 ]