std::totally_ordered, std::totally_ordered_with

From cppreference.com
< cpp‎ | concepts
Defined in header <concepts>
template < class T >

concept totally_ordered =

std::equality_comparable <T> && __PartiallyOrderedWith<T, T> ;
(1) (since C++20)
template < class T, class U >

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> & >> &&

    __PartiallyOrderedWith<T, U> ;
(2) (since C++20)
Helper concepts
template < class T, class 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 ;

} ;
(3) (exposition only*)
1) The concept std::totally_ordered specifies that the comparison operators ==,!=,<,>,<=,>= on a type yield results consistent with a strict total order
2) The concept std::totally_ordered_with specifies that the comparison operators ==,!=,<,>,<=,>= on (possibly mixed) T and U
3) The exposition-only concept __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 >=

Semantic requirements

These concepts are modeled only if they are satisfied and all concepts they subsume are modeled.

1) std::totally_ordered<T> is modeled only if, given lvalues 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)
2) std::totally_ordered_with<T, U> is modeled only if, given

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)

(until C++23)
  • static_cast < const C& > ( std::as_const (E) )
  • static_cast < const C& > (std:: move (E) )
(since C++23)

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) )
3) __PartiallyOrderedWith<T, U> is modeled only if given

the following are true:

  • t < u, t <= u, t > u, t >= u, u < t, u <= t, u > t, and u >= t
  • bool (t < u) == bool (u > t)
  • bool (u < t) == bool (t > u)
  • bool (t <= u) == bool (u >= t)
  • bool (u <= t) == bool (t >= u)

Equality preservation

Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving

Implicit expression variations

A requires expression that uses an expression that is non-modifying for some constant lvalue operand also requires implicit expression variations

References

  • C++23 standard (ISO/IEC 14882:2024):
  • 18.5.5 Concept totally_ordered [concept.totallyordered]
  • C++20 standard (ISO/IEC 14882:2020):
  • 18.5.4 Concept totally_ordered [concept.totallyordered]

See also

specifies that operator <=> produces consistent result on given types
(concept)