[cmp.categories] (original) (raw)
17 Language support library [support]
17.12 Comparisons [cmp]
17.12.2 Comparison category types [cmp.categories]
17.12.2.1 Preamble [cmp.categories.pre]
The typespartial_ordering,weak_ordering, andstrong_orderingare collectively termed the comparison category types.
Each is specified in terms of an exposition-only data member named valuewhose value typically corresponds to that of an enumerator from one of the following exposition-only enumerations:enum class ord { equal = 0, equivalent = equal, less = -1, greater = 1 }; enum class ncmp { unordered = -127 };
[Note 1:
The type strong_orderingcorresponds to the term total ordering in mathematics.
— _end note_]
The relational and equality operators for the comparison category types are specified with an anonymous parameter of unspecified type.
This type shall be selected by the implementation such that these parameters can accept literal 0 as a corresponding argument.
[Example 1:
nullptr_tmeets this requirement.
— _end example_]
In this context, the behavior of a program that supplies an argument other than a literal 0 is undefined.
For the purposes of [cmp.categories],substitutability is the property that f(a) == f(b) is truewhenever a == b is true, where f denotes a function that reads only comparison-salient state that is accessible via the argument's public const members.
17.12.2.2 Class partial_ordering [cmp.partialord]
The partial_ordering type is typically used as the result type of a three-way comparison operator ([expr.spaceship]) for a type that admits all of the six two-way comparison operators ([expr.rel], [expr.eq]), for which equality need not imply substitutability, and that permits two values to be incomparable.190
namespace std { class partial_ordering { int value; bool is_ordered; constexpr explicit partial_ordering(ord v) noexcept : value(int(v)), is_ordered(true) {} constexpr explicit partial_ordering(ncmp v) noexcept : value(int(v)), is_ordered(false) {} public: static const partial_ordering less;static const partial_ordering equivalent;static const partial_ordering greater;static const partial_ordering unordered;friend constexpr bool operator==(partial_ordering v, unspecified) noexcept;friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;friend constexpr bool operator< (partial_ordering v, _unspecified_) noexcept;friend constexpr bool operator> (partial_ordering v, unspecified) noexcept;friend constexpr bool operator<=(partial_ordering v, _unspecified_) noexcept;friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept;friend constexpr bool operator< (_unspecified_, partial_ordering v) noexcept;friend constexpr bool operator> (unspecified, partial_ordering v) noexcept;friend constexpr bool operator<=(_unspecified_, partial_ordering v) noexcept;friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept;friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept;friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept;};inline constexpr partial_ordering partial_ordering::less(ord::less);inline constexpr partial_ordering partial_ordering::equivalent(ord::equivalent);inline constexpr partial_ordering partial_ordering::greater(ord::greater);inline constexpr partial_ordering partial_ordering::unordered(ncmp::unordered);}
constexpr bool operator==(partial_ordering v, _unspecified_) noexcept;constexpr bool operator< (partial_ordering v, _unspecified_) noexcept;constexpr bool operator> (partial_ordering v, _unspecified_) noexcept;constexpr bool operator<=(partial_ordering v, _unspecified_) noexcept;constexpr bool operator>=(partial_ordering v, _unspecified_) noexcept;
Returns: For operator@, v.is_ordered && v.value @ 0.
constexpr bool operator< (_unspecified_, partial_ordering v) noexcept;constexpr bool operator> (_unspecified_, partial_ordering v) noexcept;constexpr bool operator<=(_unspecified_, partial_ordering v) noexcept;constexpr bool operator>=(_unspecified_, partial_ordering v) noexcept;
Returns: For operator@, v.is_ordered && 0 @ v.value.
constexpr partial_ordering operator<=>(partial_ordering v, _unspecified_) noexcept;
constexpr partial_ordering operator<=>(_unspecified_, partial_ordering v) noexcept;
Returns: v < 0 ? partial_ordering::greater : v > 0 ? partial_ordering::less : v.
17.12.2.3 Class weak_ordering [cmp.weakord]
The weak_ordering type is typically used as the result type of a three-way comparison operator ([expr.spaceship]) for a type that admits all of the six two-way comparison operators ([expr.rel], [expr.eq]) and for which equality need not imply substitutability.
namespace std { class weak_ordering { int value; constexpr explicit weak_ordering(ord v) noexcept : value(int(v)) {} public: static const weak_ordering less;static const weak_ordering equivalent;static const weak_ordering greater;constexpr operator partial_ordering() const noexcept;friend constexpr bool operator==(weak_ordering v, unspecified) noexcept;friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;friend constexpr bool operator< (weak_ordering v, _unspecified_) noexcept;friend constexpr bool operator> (weak_ordering v, unspecified) noexcept;friend constexpr bool operator<=(weak_ordering v, _unspecified_) noexcept;friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept;friend constexpr bool operator< (_unspecified_, weak_ordering v) noexcept;friend constexpr bool operator> (unspecified, weak_ordering v) noexcept;friend constexpr bool operator<=(_unspecified_, weak_ordering v) noexcept;friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept;friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept;friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept;};inline constexpr weak_ordering weak_ordering::less(ord::less);inline constexpr weak_ordering weak_ordering::equivalent(ord::equivalent);inline constexpr weak_ordering weak_ordering::greater(ord::greater);}
constexpr operator partial_ordering() const noexcept;
Returns: value == 0 ? partial_ordering::equivalent :value < 0 ? partial_ordering::less : partial_ordering::greater
constexpr bool operator==(weak_ordering v, _unspecified_) noexcept;constexpr bool operator< (weak_ordering v, _unspecified_) noexcept;constexpr bool operator> (weak_ordering v, _unspecified_) noexcept;constexpr bool operator<=(weak_ordering v, _unspecified_) noexcept;constexpr bool operator>=(weak_ordering v, _unspecified_) noexcept;
Returns: v.value @ 0 for operator@.
constexpr bool operator< (_unspecified_, weak_ordering v) noexcept;constexpr bool operator> (_unspecified_, weak_ordering v) noexcept;constexpr bool operator<=(_unspecified_, weak_ordering v) noexcept;constexpr bool operator>=(_unspecified_, weak_ordering v) noexcept;
Returns: 0 @ v.value for operator@.
constexpr weak_ordering operator<=>(weak_ordering v, _unspecified_) noexcept;
constexpr weak_ordering operator<=>(_unspecified_, weak_ordering v) noexcept;
Returns: v < 0 ? weak_ordering::greater : v > 0 ? weak_ordering::less : v.
17.12.2.4 Class strong_ordering [cmp.strongord]
The strong_ordering type is typically used as the result type of a three-way comparison operator ([expr.spaceship]) for a type that admits all of the six two-way comparison operators ([expr.rel], [expr.eq]) and for which equality does imply substitutability.
namespace std { class strong_ordering { int value; constexpr explicit strong_ordering(ord v) noexcept : value(int(v)) {} public: static const strong_ordering less;static const strong_ordering equal;static const strong_ordering equivalent;static const strong_ordering greater;constexpr operator partial_ordering() const noexcept;constexpr operator weak_ordering() const noexcept;friend constexpr bool operator==(strong_ordering v, unspecified) noexcept;friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;friend constexpr bool operator< (strong_ordering v, _unspecified_) noexcept;friend constexpr bool operator> (strong_ordering v, unspecified) noexcept;friend constexpr bool operator<=(strong_ordering v, _unspecified_) noexcept;friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept;friend constexpr bool operator< (_unspecified_, strong_ordering v) noexcept;friend constexpr bool operator> (unspecified, strong_ordering v) noexcept;friend constexpr bool operator<=(_unspecified_, strong_ordering v) noexcept;friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept;friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept;friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept;};inline constexpr strong_ordering strong_ordering::less(ord::less);inline constexpr strong_ordering strong_ordering::equal(ord::equal);inline constexpr strong_ordering strong_ordering::equivalent(ord::equivalent);inline constexpr strong_ordering strong_ordering::greater(ord::greater);}
constexpr operator partial_ordering() const noexcept;
Returns: value == 0 ? partial_ordering::equivalent :value < 0 ? partial_ordering::less : partial_ordering::greater
constexpr operator weak_ordering() const noexcept;
Returns: value == 0 ? weak_ordering::equivalent :value < 0 ? weak_ordering::less : weak_ordering::greater
constexpr bool operator==(strong_ordering v, _unspecified_) noexcept;constexpr bool operator< (strong_ordering v, _unspecified_) noexcept;constexpr bool operator> (strong_ordering v, _unspecified_) noexcept;constexpr bool operator<=(strong_ordering v, _unspecified_) noexcept;constexpr bool operator>=(strong_ordering v, _unspecified_) noexcept;
Returns: v.value @ 0 for operator@.
constexpr bool operator< (_unspecified_, strong_ordering v) noexcept;constexpr bool operator> (_unspecified_, strong_ordering v) noexcept;constexpr bool operator<=(_unspecified_, strong_ordering v) noexcept;constexpr bool operator>=(_unspecified_, strong_ordering v) noexcept;
Returns: 0 @ v.value for operator@.
constexpr strong_ordering operator<=>(strong_ordering v, _unspecified_) noexcept;
constexpr strong_ordering operator<=>(_unspecified_, strong_ordering v) noexcept;
Returns: v < 0 ? strong_ordering::greater : v > 0 ? strong_ordering::less : v.