This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

124
cppdraft/expr/spaceship.md Normal file
View File

@@ -0,0 +1,124 @@
[expr.spaceship]
# 7 Expressions [[expr]](./#expr)
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.spaceship)
### 7.6.8 Three-way comparison operator [expr.spaceship]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7283)
The three-way comparison operator groups left-to-right[.](#1.sentence-1)
[compare-expression:](#nt:compare-expression "7.6.8Three-way comparison operator[expr.spaceship]")
[*shift-expression*](expr.shift#nt:shift-expression "7.6.7Shift operators[expr.shift]")
[*compare-expression*](#nt:compare-expression "7.6.8Three-way comparison operator[expr.spaceship]") <=> [*shift-expression*](expr.shift#nt:shift-expression "7.6.7Shift operators[expr.shift]")
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7296)
The expression p <=> q is a prvalue indicating whetherp is less than, equal to, greater than, or incomparable withq[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7301)
If one of the operands is of type bool and the other is not, the program is ill-formed[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7305)
If both operands have arithmetic types,
or one operand has integral type and
the other operand has unscoped enumeration type,
the [usual arithmetic conversions](expr.arith.conv "7.4Usual arithmetic conversions[expr.arith.conv]") are applied to the operands[.](#4.sentence-1)
Then:
- [(4.1)](#4.1)
If a [narrowing conversion](dcl.init.list#def:conversion,narrowing "9.5.5List-initialization[dcl.init.list]") is required,
other than from an integral type to a floating-point type,
the program is ill-formed[.](#4.1.sentence-1)
- [(4.2)](#4.2)
Otherwise, if the operands have integral type,
the result is of type std::strong_ordering[.](#4.2.sentence-1)
The result isstd::strong_ordering::equal if both operands are arithmetically equal,std::strong_ordering::less if the first operand is arithmetically
less than the second operand,
andstd::strong_ordering::greater otherwise[.](#4.2.sentence-2)
- [(4.3)](#4.3)
Otherwise, the operands have floating-point type, and
the result is of type std::partial_ordering[.](#4.3.sentence-1)
The expression a <=> b yieldsstd::partial_ordering::less if a is less than b,std::partial_ordering::greater if a is greater than b,std::partial_ordering::equivalent if a is equivalent to b,
andstd::partial_ordering::unordered otherwise[.](#4.3.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7343)
If both operands have the same enumeration type E,
the operator yields the result of
converting the operands to the underlying type of E and applying <=> to the converted operands[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7349)
If at least one of the operands is of object pointer type and
the other operand is of object pointer or array type,
array-to-pointer conversions ([[conv.array]](conv.array "7.3.3Array-to-pointer conversion")),
pointer conversions ([[conv.ptr]](conv.ptr "7.3.12Pointer conversions")),
and[qualification conversions](conv.qual "7.3.6Qualification conversions[conv.qual]") are performed on both operands
to bring them to their composite pointer type ([[expr.type]](expr.type "7.2.2Type"))[.](#6.sentence-1)
After the conversions, the operands shall have the same type[.](#6.sentence-2)
[*Note [1](#note-1)*:
If both of the operands are arrays,[array-to-pointer conversions](conv.array "7.3.3Array-to-pointer conversion[conv.array]") are not applied[.](#6.sentence-3)
— *end note*]
In this case,p <=> q is of type std::strong_ordering and
the result is defined by the following rules:
- [(6.1)](#6.1)
If two pointer operands p and q compare equal ([[expr.eq]](expr.eq "7.6.10Equality operators")),p <=> q yields std::strong_ordering::equal;
- [(6.2)](#6.2)
otherwise, if p and q compare unequal,p <=> q yieldsstd::strong_ordering::less if q compares greater than p andstd::strong_ordering::greater if p compares greater than q ([[expr.rel]](expr.rel "7.6.9Relational operators"));
- [(6.3)](#6.3)
otherwise, the result is unspecified[.](#6.sentence-4)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7382)
Otherwise, the program is ill-formed[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7385)
The three comparison category types ([[cmp.categories]](cmp.categories "17.12.2Comparison category types"))
(the typesstd::strong_ordering,std::weak_ordering, andstd::partial_ordering)
are not predefined;
if a standard library declaration ([[compare.syn]](compare.syn "17.12.1Header <compare> synopsis"), [[std.modules]](std.modules "16.4.2.4Modules"))
of such a class type does not precede ([[basic.lookup.general]](basic.lookup.general "6.5.1General"))
a use of that type —
even an implicit use in which the type is not named
(e.g., via the auto specifier ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers"))
in a defaulted three-way comparison ([[class.spaceship]](class.spaceship "11.10.3Three-way comparison"))
or use of the built-in operator) — the program is ill-formed[.](#8.sentence-1)