std::totally_ordered, std::totally_ordered_with
<concepts>
concept totally_ordered =
concept totally_ordered_with =
std::totally_ordered<T> &&
std::totally_ordered<U> &&
std::equality_comparable_with <T, U> &&
std::totally_ordered<
std::common_reference_t <
const std::remove_reference_t <T>&,
const std::remove_reference_t <U>&>> &&
concept __PartiallyOrderedWith =
requires(const std::remove_reference_t <T>& t,
const std::remove_reference_t <U>& u) {
{ t < u } -> boolean-testable ;
{ t > u } -> boolean-testable ;
{ t <= u } -> boolean-testable ;
{ t >= u } -> boolean-testable ;
{ u < t } -> boolean-testable ;
{ u > t } -> boolean-testable ;
{ u <= t } -> boolean-testable ;
{ u >= t } -> boolean-testable ;
std::totally_ordered
specifies that the comparison operators ==,!=,<,>,<=,>=
on a type yield results consistent with a strict total order on the type.std::totally_ordered_with
specifies that the comparison operators ==,!=,<,>,<=,>=
on (possibly mixed) T
and U
operands yield results consistent with a strict total order. Comparing mixed operands yields results equivalent to comparing the operands converted to their common type.__PartiallyOrderedWith
specifies that a value of type T
and a value of type U
can be compared in a partial order with each other (in either order) using <
, >
, <=
, and >=
, and the results of the comparisons are consistent.Contents
[edit] Semantic requirements
These concepts are modeled only if they are satisfied and all concepts they subsume are modeled.
a
, b
and c
of type const std::remove_reference_t <T>:
- Exactly one of bool(a < b), bool(a > b) and bool(a == b) is true;
- If bool(a < b) and bool(b < c) are both true, then bool(a < c) is true;
- bool(a > b) == bool(b < a)
- bool(a >= b) == !bool(a < b)
- bool(a <= b) == !bool(b < a)
-
t
andt2
, lvalues denoting distinct equal objects of types const std::remove_reference_t <T> and std::remove_reference_t <T> respectively, and -
u
andu2
, lvalues denoting distinct equal objects of types const std::remove_reference_t <U> and std::remove_reference_t <U> respectively,
let C
be std::common_reference_t <const std::remove_reference_t <T>&, const std::remove_reference_t <U>&>, and, given an expression E
and a type C
, let CONVERT_TO<C>(E) be:
- static_cast<C>(std::as_const (E)).
- static_cast<const C&>(std::as_const (E)) if that is a valid expression,
- static_cast<const C&>(std::move(E)) otherwise.
the following are true:
- bool(t < u) == bool(CONVERT_TO<C>(t2) < CONVERT_TO<C>(u2))
- bool(t > u) == bool(CONVERT_TO<C>(t2) > CONVERT_TO<C>(u2))
- bool(t <= u) == bool(CONVERT_TO<C>(t2) <= CONVERT_TO<C>(u2))
- bool(t >= u) == bool(CONVERT_TO<C>(t2) >= CONVERT_TO<C>(u2))
- bool(u < t) == bool(CONVERT_TO<C>(u2) < CONVERT_TO<C>(t2))
- bool(u > t) == bool(CONVERT_TO<C>(u2) > CONVERT_TO<C>(t2))
- bool(u <= t) == bool(CONVERT_TO<C>(u2) <= CONVERT_TO<C>(t2))
- bool(u >= t) == bool(CONVERT_TO<C>(u2) >= CONVERT_TO<C>(t2))
- any lvalue
t
of type const std::remove_reference_t <T>, and - any lvalue
u
of type const std::remove_reference_t <U>,
the following are true:
- t < u, t <= u, t > u, t >= u, u < t, u <= t, u > t, and u >= t have the same domain;
- bool(t < u) == bool(u > t);
- bool(u < t) == bool(t > u);
- bool(t <= u) == bool(u >= t); and
- bool(u <= t) == bool(t >= u).
[edit] Equality preservation
Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving (except where stated otherwise).
[edit] Implicit expression variations
A requires expression that uses an expression that is non-modifying for some constant lvalue operand also requires implicit expression variations.
[edit] References
- C++23 standard (ISO/IEC 14882:2024):
- 18.5.5 Concept
totally_ordered
[concept.totallyordered]
- 18.5.5 Concept
- C++20 standard (ISO/IEC 14882:2020):
- 18.5.4 Concept
totally_ordered
[concept.totallyordered]
- 18.5.4 Concept