1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class T, class Cat = partial_ordering>
12 // concept three_way_comparable = // see below
16 #include "compare_types.h"
17 #include "test_macros.h"
19 namespace fundamentals
{
20 // with default ordering
21 static_assert(std::three_way_comparable
<int>);
22 static_assert(std::three_way_comparable
<double>);
23 static_assert(std::three_way_comparable
<void*>);
24 static_assert(std::three_way_comparable
<char*>);
25 static_assert(std::three_way_comparable
<char const*>);
26 static_assert(std::three_way_comparable
<char volatile*>);
27 static_assert(std::three_way_comparable
<char const volatile*>);
28 static_assert(std::three_way_comparable
<wchar_t&>);
29 #ifndef TEST_HAS_NO_CHAR8_T
30 static_assert(std::three_way_comparable
<char8_t
const&>);
32 static_assert(std::three_way_comparable
<char16_t
volatile&>);
33 static_assert(std::three_way_comparable
<char32_t
const volatile&>);
34 #ifndef TEST_HAS_NO_INT128
35 static_assert(std::three_way_comparable
<__int128_t
const&>);
36 static_assert(std::three_way_comparable
<__uint128_t
const&>);
38 static_assert(std::three_way_comparable
<unsigned char&&>);
39 static_assert(std::three_way_comparable
<unsigned short const&&>);
40 static_assert(std::three_way_comparable
<unsigned int volatile&&>);
41 static_assert(std::three_way_comparable
<unsigned long const volatile&&>);
43 // with explicit ordering
44 static_assert(std::three_way_comparable
<int, std::strong_ordering
>);
45 static_assert(std::three_way_comparable
<int, std::weak_ordering
>);
46 static_assert(std::three_way_comparable
<double, std::partial_ordering
>);
47 static_assert(!std::three_way_comparable
<double, std::weak_ordering
>);
48 static_assert(std::three_way_comparable
<void*, std::strong_ordering
>);
49 static_assert(std::three_way_comparable
<void*, std::weak_ordering
>);
50 static_assert(std::three_way_comparable
<char*, std::strong_ordering
>);
51 static_assert(std::three_way_comparable
<char*, std::weak_ordering
>);
52 static_assert(std::three_way_comparable
<char const*, std::strong_ordering
>);
53 static_assert(std::three_way_comparable
<char const*, std::weak_ordering
>);
54 static_assert(std::three_way_comparable
<char volatile*, std::strong_ordering
>);
55 static_assert(std::three_way_comparable
<char volatile*, std::weak_ordering
>);
56 static_assert(std::three_way_comparable
<char const volatile*, std::strong_ordering
>);
57 static_assert(std::three_way_comparable
<char const volatile*, std::weak_ordering
>);
58 static_assert(std::three_way_comparable
<wchar_t&, std::strong_ordering
>);
59 static_assert(std::three_way_comparable
<wchar_t&, std::weak_ordering
>);
60 static_assert(std::three_way_comparable
<char8_t
const&, std::strong_ordering
>);
61 static_assert(std::three_way_comparable
<char8_t
const&, std::weak_ordering
>);
62 static_assert(std::three_way_comparable
<char16_t
volatile&, std::strong_ordering
>);
63 static_assert(std::three_way_comparable
<char16_t
volatile&, std::weak_ordering
>);
64 static_assert(std::three_way_comparable
<char32_t
const volatile&, std::strong_ordering
>);
65 static_assert(std::three_way_comparable
<char32_t
const volatile&, std::weak_ordering
>);
66 static_assert(std::three_way_comparable
<unsigned char&&, std::strong_ordering
>);
67 static_assert(std::three_way_comparable
<unsigned char&&, std::weak_ordering
>);
68 static_assert(std::three_way_comparable
<unsigned short const&&, std::strong_ordering
>);
69 static_assert(std::three_way_comparable
<unsigned short const&&, std::weak_ordering
>);
70 static_assert(std::three_way_comparable
<unsigned int volatile&&, std::strong_ordering
>);
71 static_assert(std::three_way_comparable
<unsigned int volatile&&, std::weak_ordering
>);
72 static_assert(std::three_way_comparable
<unsigned long const volatile&&, std::strong_ordering
>);
73 static_assert(std::three_way_comparable
<unsigned long const volatile&&, std::weak_ordering
>);
75 static_assert(!std::three_way_comparable
<int[5]>);
76 static_assert(!std::three_way_comparable
<int (*)(int)>);
77 static_assert(!std::three_way_comparable
<int (&)(int)>);
78 static_assert(!std::three_way_comparable
<int (*)(int) noexcept
>);
79 static_assert(!std::three_way_comparable
<int (&)(int) noexcept
>);
80 static_assert(!std::three_way_comparable
<std::nullptr_t
>);
81 static_assert(!std::three_way_comparable
<void>);
84 static_assert(!std::three_way_comparable
<int S::*>);
85 static_assert(!std::three_way_comparable
<int (S::*)()>);
86 static_assert(!std::three_way_comparable
<int (S::*)() noexcept
>);
87 static_assert(!std::three_way_comparable
<int (S::*)() &>);
88 static_assert(!std::three_way_comparable
<int (S::*)() & noexcept
>);
89 static_assert(!std::three_way_comparable
<int (S::*)() &&>);
90 static_assert(!std::three_way_comparable
<int (S::*)() && noexcept
>);
91 static_assert(!std::three_way_comparable
<int (S::*)() const>);
92 static_assert(!std::three_way_comparable
<int (S::*)() const noexcept
>);
93 static_assert(!std::three_way_comparable
<int (S::*)() const&>);
94 static_assert(!std::three_way_comparable
<int (S::*)() const & noexcept
>);
95 static_assert(!std::three_way_comparable
<int (S::*)() const&&>);
96 static_assert(!std::three_way_comparable
<int (S::*)() const && noexcept
>);
97 static_assert(!std::three_way_comparable
<int (S::*)() volatile>);
98 static_assert(!std::three_way_comparable
<int (S::*)() volatile noexcept
>);
99 static_assert(!std::three_way_comparable
<int (S::*)() volatile&>);
100 static_assert(!std::three_way_comparable
<int (S::*)() volatile & noexcept
>);
101 static_assert(!std::three_way_comparable
<int (S::*)() volatile&&>);
102 static_assert(!std::three_way_comparable
<int (S::*)() volatile && noexcept
>);
103 static_assert(!std::three_way_comparable
<int (S::*)() const volatile>);
104 static_assert(!std::three_way_comparable
<int (S::*)() const volatile noexcept
>);
105 static_assert(!std::three_way_comparable
<int (S::*)() const volatile&>);
106 static_assert(!std::three_way_comparable
<int (S::*)() const volatile & noexcept
>);
107 static_assert(!std::three_way_comparable
<int (S::*)() const volatile&&>);
108 static_assert(!std::three_way_comparable
<int (S::*)() const volatile && noexcept
>);
109 } // namespace fundamentals
111 namespace user_defined
{
114 auto operator<=>(const S
&) const = default;
117 static_assert(std::three_way_comparable
<S
>);
118 static_assert(std::three_way_comparable
<S
, std::strong_ordering
>);
119 static_assert(std::three_way_comparable
<S
, std::partial_ordering
>);
121 struct SpaceshipNotDeclared
{
124 static_assert(!std::three_way_comparable
<SpaceshipNotDeclared
>);
126 struct SpaceshipDeleted
{
127 auto operator<=>(const SpaceshipDeleted
&) const = delete;
130 static_assert(!std::three_way_comparable
<SpaceshipDeleted
>);
132 struct SpaceshipWithoutEqualityOperator
{
133 auto operator<=>(const SpaceshipWithoutEqualityOperator
&) const;
136 static_assert(!std::three_way_comparable
<SpaceshipWithoutEqualityOperator
>);
138 struct EqualityOperatorDeleted
{
139 bool operator==(const EqualityOperatorDeleted
&) const = delete;
142 static_assert(!std::three_way_comparable
<EqualityOperatorDeleted
>);
144 struct EqualityOperatorOnly
{
145 bool operator==(const EqualityOperatorOnly
&) const = default;
148 static_assert(!std::three_way_comparable
<EqualityOperatorOnly
>);
150 struct SpaceshipDeclaredEqualityOperatorDeleted
{
151 bool operator==(const SpaceshipDeclaredEqualityOperatorDeleted
&) const = delete;
152 auto operator<=>(const SpaceshipDeclaredEqualityOperatorDeleted
&) const = default;
155 static_assert(!std::three_way_comparable
<SpaceshipDeclaredEqualityOperatorDeleted
>);
157 struct AllInequalityOperators
{
158 bool operator<(const AllInequalityOperators
&) const;
159 bool operator<=(const AllInequalityOperators
&) const;
160 bool operator>(const AllInequalityOperators
&) const;
161 bool operator>=(const AllInequalityOperators
&) const;
162 bool operator!=(const AllInequalityOperators
&) const;
165 static_assert(!std::three_way_comparable
<AllInequalityOperators
>);
167 struct AllComparisonOperators
{
168 bool operator<(const AllComparisonOperators
&) const;
169 bool operator<=(const AllComparisonOperators
&) const;
170 bool operator>(const AllComparisonOperators
&) const;
171 bool operator>=(const AllComparisonOperators
&) const;
172 bool operator!=(const AllComparisonOperators
&) const;
173 bool operator==(const AllComparisonOperators
&) const;
176 static_assert(!std::three_way_comparable
<AllComparisonOperators
>);
178 struct AllButOneInequalityOperators
{
179 bool operator<(const AllButOneInequalityOperators
&) const;
180 bool operator<=(const AllButOneInequalityOperators
&) const;
181 bool operator>(const AllButOneInequalityOperators
&) const;
182 bool operator!=(const AllButOneInequalityOperators
&) const;
185 static_assert(!std::three_way_comparable
<AllButOneInequalityOperators
>);
187 struct AllInequalityOperatorsOneDeleted
{
188 bool operator<(const AllInequalityOperatorsOneDeleted
&) const;
189 bool operator<=(const AllInequalityOperatorsOneDeleted
&) const;
190 bool operator>(const AllInequalityOperatorsOneDeleted
&) const;
191 bool operator>=(const AllInequalityOperatorsOneDeleted
&) const = delete;
192 bool operator!=(const AllInequalityOperatorsOneDeleted
&) const;
195 static_assert(!std::three_way_comparable
<AllInequalityOperatorsOneDeleted
>);
197 struct EqualityOperatorWrongReturnType
{
198 int operator==(const EqualityOperatorWrongReturnType
&);
199 auto operator<=>(const EqualityOperatorWrongReturnType
&) const = default;
202 static_assert(!std::three_way_comparable
<EqualityOperatorWrongReturnType
>);
204 struct SpaceshipWrongReturnType
{
205 bool operator==(const SpaceshipWrongReturnType
&) const = default;
206 int operator<=>(const SpaceshipWrongReturnType
&);
209 static_assert(!std::three_way_comparable
<SpaceshipWrongReturnType
>);
211 struct EqualityOperatorNonConstArgument
{
212 bool operator==(EqualityOperatorNonConstArgument
&);
213 auto operator<=>(const EqualityOperatorNonConstArgument
&) const = default;
216 static_assert(!std::three_way_comparable
<EqualityOperatorNonConstArgument
>);
218 struct SpaceshipNonConstArgument
{
219 bool operator==(const SpaceshipNonConstArgument
&) const = default;
220 auto operator<=>(SpaceshipNonConstArgument
&);
223 static_assert(!std::three_way_comparable
<SpaceshipNonConstArgument
>);
224 } // namespace user_defined