std::three_way_comparable, std::three_way_comparable_with - cppreference.com (original) (raw)
| Defined in header | ||
|---|---|---|
| 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*) |
The concept
std::three_way_comparablespecifies that the three way comparison operator<=>onTyield results consistent with the comparison category implied byCat.The concept
std::three_way_comparable_withspecifies that the three way comparison operator<=>on (possibly mixed)TandUoperands yield results consistent with the comparison category implied byCat. Comparing mixed operands yields results equivalent to comparing the operands converted to their common type.
__WeaklyEqualityComparableWith, __PartiallyOrderedWith, and __ComparisonCommonTypeWith are exposition-only concepts. See descriptions of equality_comparable and totally_ordered.
Contents
[edit] Semantic requirements
These concepts are modeled only if they are satisfied and all concepts they subsume are modeled.
TandCatmodel std::three_way_comparable<T, Cat> only if, given lvaluesaandbof 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)) are equal,
- 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), and
- (a <=> b >= 0) == bool(a >= b), and
- if
Catis convertible to std::strong_ordering,Tmodels totally_ordered.
T,U, andCatmodel std::three_way_comparable_with<T, U, Cat> only if given
tandt2, lvalues denoting distinct equal objects of types const std::remove_reference_t<T> and std::remove_reference_t<T> respectively, anduandu2, 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)). | (until C++23) |
|---|---|
| static_cast<const C&>(std::as_const(E)) if that is a valid expression, static_cast<const C&>(std::move(E)) otherwise. | (since C++23) |
the following are true:
- t <=> u and u <=> t have the same domain,
- ((t <=> u) <=> 0) and (0 <=> (u <=> t)) are equal,
- (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), and
- if
Catis convertible to std::strong_ordering,TandUmodel std::totally_ordered_with<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.