std::three_way_comparable, std::three_way_comparable_with

From cppreference.com
< cpp‎ | utility
Utilities library
General utilities
Relational operators (deprecated in C++20)
Integer comparison functions
(C++20)(C++20)(C++20)
(C++20)
Swap and type operations
(C++20)
(C++14)
(C++11)
(C++23)
(C++11)
(C++23)
(C++11)
(C++17)
Common vocabulary types
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++11)
(C++17)
(C++17)
(C++23)



Defined in header <compare>
template < class T, class Cat = std::partial_ordering >

concept three_way_comparable =
    __WeaklyEqualityComparableWith<T, T> &&
    __PartiallyOrderedWith<T, T> &&
    requires( const std::remove_reference_t <T> & a,
const std::remove_reference_t <T> & b) {
{ a <=> b } - > __ComparesAs<Cat> ;

} ;
(1) (since C++20)
template < class T, class U, class Cat = std::partial_ordering >

concept three_way_comparable_with =
    std:: three_way_comparable <T, Cat> &&
    std:: three_way_comparable <U, Cat> &&
    __ComparisonCommonTypeWith<T, U> &&
    std:: three_way_comparable <
std::common_reference_t <
const std::remove_reference_t <T> &,
const std::remove_reference_t <U> & >, Cat> &&
    __WeaklyEqualityComparableWith<T, U> &&
    __PartiallyOrderedWith<T, U> &&
    requires( const std::remove_reference_t <T> & t,
const std::remove_reference_t <U> & u) {
{ t <=> u } - > __ComparesAs<Cat> ;
{ u <=> t } - > __ComparesAs<Cat> ;

} ;
(2) (since C++20)
template < class T, class Cat >

concept __ComparesAs =

std::same_as < std::common_comparison_category_t <T, Cat>, Cat> ;
(3) (exposition only*)
1) The concept std::three_way_comparable specifies that the three way comparison operator <=> on T yield results consistent with the comparison category implied by Cat
2) The concept std::three_way_comparable_with specifies that the three way comparison operator <=> on (possibly mixed) T and U operands yield results consistent with the comparison category implied by Cat

__WeaklyEqualityComparableWith, __PartiallyOrderedWith, and __ComparisonCommonTypeWith are exposition-only concepts. See descriptions of equality_comparable and totally_ordered

Semantic requirements

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

1) T and Cat model std::three_way_comparable<T, Cat> only if, given lvalues a and b of type const std::remove_reference_t <T> , following are true:
  • (a <=> b == 0 ) == bool (a == b)
  • (a <=> b ! = 0 ) == bool (a ! = b)
  • ((a <=> b) <=> 0) and (0 <=> (b <=> a))
  • bool (a > b) == bool (b < a)
  • bool (a >= b) == ! bool (a < b)
  • bool (a <= b) == ! bool (b < a)
  • (a <=> b < 0 ) == bool (a < b)
  • (a <=> b > 0 ) == bool (a > b)
  • (a <=> b <= 0 ) == bool (a <= b)
  • (a <=> b >= 0 ) == bool (a >= b)
  • if Cat is convertible to std::strong_ordering, T models totally_ordered.
2) T, U, and Cat model std::three_way_comparable_with<T, U, Cat> 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:

  • t <=> u and u <=> t
  • ((t <=> u) <=> 0) and (0 <=> (u <=> t))
  • (t <=> u == 0 ) == bool (t == u)
  • (t <=> u ! = 0 ) == bool (t ! = u)
  • Cat(t <=> u) == Cat(CONVERT_TO<C> (t2) <=> CONVERT_TO<C> (u2) )
  • (t <=> u < 0 ) == bool (t < u)
  • (t <=> u > 0 ) == bool (t > u)
  • (t <=> u <= 0 ) == bool (t <= u)
  • (t <=> u >= 0 ) == bool (t >= u)
  • if Cat is convertible to std::strong_ordering, T and U model std::totally_ordered_with<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

See also

specifies that operator == is an equivalence relation
(concept)
specifies that the comparison operators on the type yield a total order
(concept)