[cmp.categories]

# 17 Language support library [[support]](./#support)

## 17.12 Comparisons [[cmp]](cmp#categories)

### 17.12.2 Comparison category types [cmp.categories]

#### [17.12.2.1](#pre) Preamble [[cmp.categories.pre]](cmp.categories.pre)

[1](#pre-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4859)

The typespartial_ordering,weak_ordering, andstrong_ordering are collectively termed the [*comparison category types*](#def:comparison_category_types "17.12.2.1 Preamble [cmp.categories.pre]")[.](#pre-1.sentence-1)

Each is specified in terms of an exposition-only data member named value whose 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 }; // *exposition only*enum class *ncmp* { *unordered* = -127 }; // *exposition only*

[2](#pre-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4873)

[*Note [1](#pre-note-1)*:

The type strong_ordering corresponds to the term
total ordering in mathematics[.](#pre-2.sentence-1)

â *end note*]

[3](#pre-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4880)

The relational and equality operators for the comparison category types
are specified with an anonymous parameter of unspecified type[.](#pre-3.sentence-1)

This type shall be selected by the implementation such that
these parameters can accept literal 0 as a corresponding argument[.](#pre-3.sentence-2)

[*Example [1](#pre-example-1)*:

nullptr_t meets this requirement[.](#pre-3.sentence-3)

â *end example*]

In this context, the behavior of a program that supplies
an argument other than a literal 0 is undefined[.](#pre-3.sentence-4)

[4](#pre-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4892)

For the purposes of [cmp.categories],[*substitutability*](#def:substitutability "17.12.2.1 Preamble [cmp.categories.pre]") is the property that f(a) == f(b) is true whenever 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[.](#pre-4.sentence-1)

#### [17.12.2.2](#cmp.partialord) Class partial_ordering [[cmp.partialord]](cmp.partialord)

[1](#cmp.partialord-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4901)

The partial_ordering type is typically used
as the result type of a three-way comparison operator ([[expr.spaceship]](expr.spaceship "7.6.8 Three-way comparison operator"))
for a type that admits
all of the six two-way comparison operators ([[expr.rel]](expr.rel "7.6.9 Relational operators"), [[expr.eq]](expr.eq "7.6.10 Equality operators")),
for which equality need not imply substitutability,
and that permits two values to be incomparable[.](#cmp.partialord-1.sentence-1)[190](#footnote-190 "That is, a &lt; b, a == b, and a > b might all be false.")

[ð](#lib:partial_ordering)

namespace std {class partial_ordering {int *value*; // *exposition only*bool *is-ordered*; // *exposition only*// exposition-only constructorsconstexpr explicit partial_ordering(*ord* v) noexcept : *value*(int(v)), *is-ordered*(true) {} // *exposition only*constexpr explicit partial_ordering(*ncmp* v) noexcept : *value*(int(v)), *is-ordered*(false) {} // *exposition only*public:// valid valuesstatic const partial_ordering less; static const partial_ordering equivalent; static const partial_ordering greater; static const partial_ordering unordered; // comparisonsfriend 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; }; // valid values' definitionsinline 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*);}

[ð](#lib:operator==,partial_ordering)

`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;
`

[2](#cmp.partialord-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4973)

*Returns*: For operator@, v.*is-ordered* && v.*value* @ 0[.](#cmp.partialord-2.sentence-1)

[ð](#lib:operator%3c,partial_ordering_)

`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;
`

[3](#cmp.partialord-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4990)

*Returns*: For operator@, v.*is-ordered* && 0 @ v.*value*[.](#cmp.partialord-3.sentence-1)

[ð](#lib:operator%3c=%3e,partial_ordering)

`constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept;
`

[4](#cmp.partialord-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5001)

*Returns*: v[.](#cmp.partialord-4.sentence-1)

[ð](#lib:operator%3c=%3e,partial_ordering_)

`constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept;
`

[5](#cmp.partialord-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5012)

*Returns*: v < 0 ? partial_ordering​::​greater : v > 0 ? partial_ordering​::​less : v[.](#cmp.partialord-5.sentence-1)

[190)](#footnote-190)[190)](#footnoteref-190)

That is, a < b, a == b, and a > b might all be false[.](#footnote-190.sentence-1)

#### [17.12.2.3](#cmp.weakord) Class weak_ordering [[cmp.weakord]](cmp.weakord)

[1](#cmp.weakord-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5019)

The weak_ordering type is typically used
as the result type of a three-way comparison operator ([[expr.spaceship]](expr.spaceship "7.6.8 Three-way comparison operator"))
for a type that admits
all of the six two-way comparison operators ([[expr.rel]](expr.rel "7.6.9 Relational operators"), [[expr.eq]](expr.eq "7.6.10 Equality operators"))
and for which equality need not imply substitutability[.](#cmp.weakord-1.sentence-1)

[ð](#lib:weak_ordering)

namespace std {class weak_ordering {int *value*; // *exposition only*// exposition-only constructorsconstexpr explicit weak_ordering(*ord* v) noexcept : *value*(int(v)) {} // *exposition only*public:// valid valuesstatic const weak_ordering less; static const weak_ordering equivalent; static const weak_ordering greater; // conversionsconstexpr operator partial_ordering() const noexcept; // comparisonsfriend 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; }; // valid values' definitionsinline 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*);}

[ð](#lib:operator_partial_ordering,weak_ordering)

`constexpr operator partial_ordering() const noexcept;
`

[2](#cmp.weakord-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5075)

*Returns*: *value* == 0 ? partial_ordering::equivalent :*value* < 0 ? partial_ordering::less : partial_ordering::greater

[ð](#lib:operator==,weak_ordering)

`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;
`

[3](#cmp.weakord-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5098)

*Returns*: v.*value* @ 0 for operator@[.](#cmp.weakord-3.sentence-1)

[ð](#lib:operator%3c,weak_ordering_)

`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;
`

[4](#cmp.weakord-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5115)

*Returns*: 0 @ v.*value* for operator@[.](#cmp.weakord-4.sentence-1)

[ð](#lib:operator%3c=%3e,weak_ordering)

`constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept;
`

[5](#cmp.weakord-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5126)

*Returns*: v[.](#cmp.weakord-5.sentence-1)

[ð](#lib:operator%3c=%3e,weak_ordering_)

`constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept;
`

[6](#cmp.weakord-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5137)

*Returns*: v < 0 ? weak_ordering​::​greater : v > 0 ? weak_ordering​::​less : v[.](#cmp.weakord-6.sentence-1)

#### [17.12.2.4](#cmp.strongord) Class strong_ordering [[cmp.strongord]](cmp.strongord)

[1](#cmp.strongord-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5144)

The strong_ordering type is typically used
as the result type of a three-way comparison operator ([[expr.spaceship]](expr.spaceship "7.6.8 Three-way comparison operator"))
for a type that admits
all of the six two-way comparison operators ([[expr.rel]](expr.rel "7.6.9 Relational operators"), [[expr.eq]](expr.eq "7.6.10 Equality operators"))
and for which equality does imply substitutability[.](#cmp.strongord-1.sentence-1)

[ð](#lib:strong_ordering)

namespace std {class strong_ordering {int *value*; // *exposition only*// exposition-only constructorsconstexpr explicit strong_ordering(*ord* v) noexcept : *value*(int(v)) {} // *exposition only*public:// valid valuesstatic const strong_ordering less; static const strong_ordering equal; static const strong_ordering equivalent; static const strong_ordering greater; // conversionsconstexpr operator partial_ordering() const noexcept; constexpr operator weak_ordering() const noexcept; // comparisonsfriend 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; }; // valid values' definitionsinline 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*);}

[ð](#lib:operator_partial_ordering,strong_ordering)

`constexpr operator partial_ordering() const noexcept;
`

[2](#cmp.strongord-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5204)

*Returns*: *value* == 0 ? partial_ordering::equivalent :*value* < 0 ? partial_ordering::less : partial_ordering::greater

[ð](#lib:operator_weak_ordering,strong_ordering)

`constexpr operator weak_ordering() const noexcept;
`

[3](#cmp.strongord-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5219)

*Returns*: *value* == 0 ? weak_ordering::equivalent :*value* < 0 ? weak_ordering::less : weak_ordering::greater

[ð](#lib:operator==,strong_ordering)

`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;
`

[4](#cmp.strongord-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5242)

*Returns*: v.*value* @ 0 for operator@[.](#cmp.strongord-4.sentence-1)

[ð](#lib:operator%3c,strong_ordering_)

`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;
`

[5](#cmp.strongord-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5259)

*Returns*: 0 @ v.*value* for operator@[.](#cmp.strongord-5.sentence-1)

[ð](#lib:operator%3c=%3e,strong_ordering)

`constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept;
`

[6](#cmp.strongord-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5270)

*Returns*: v[.](#cmp.strongord-6.sentence-1)

[ð](#lib:operator%3c=%3e,strong_ordering_)

`constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept;
`

[7](#cmp.strongord-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L5281)

*Returns*: v < 0 ? strong_ordering​::​greater : v > 0 ? strong_ordering​::​less : v[.](#cmp.strongord-7.sentence-1)
