1//===----------------------------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11// template<class T, class Cat = partial_ordering>
12// concept three_way_comparable = // see below
13
14#include <compare>
15#include <cstddef>
16
17#include "compare_types.h"
18#include "test_macros.h"
19
20namespace fundamentals {
21// with default ordering
22static_assert(std::three_way_comparable<int>);
23static_assert(std::three_way_comparable<double>);
24static_assert(std::three_way_comparable<void*>);
25static_assert(std::three_way_comparable<char*>);
26static_assert(std::three_way_comparable<char const*>);
27static_assert(std::three_way_comparable<char volatile*>);
28static_assert(std::three_way_comparable<char const volatile*>);
29static_assert(std::three_way_comparable<wchar_t&>);
30#ifndef TEST_HAS_NO_CHAR8_T
31static_assert(std::three_way_comparable<char8_t const&>);
32#endif
33static_assert(std::three_way_comparable<char16_t volatile&>);
34static_assert(std::three_way_comparable<char32_t const volatile&>);
35#ifndef TEST_HAS_NO_INT128
36static_assert(std::three_way_comparable<__int128_t const&>);
37static_assert(std::three_way_comparable<__uint128_t const&>);
38#endif
39static_assert(std::three_way_comparable<unsigned char&&>);
40static_assert(std::three_way_comparable<unsigned short const&&>);
41static_assert(std::three_way_comparable<unsigned int volatile&&>);
42static_assert(std::three_way_comparable<unsigned long const volatile&&>);
43
44// with explicit ordering
45static_assert(std::three_way_comparable<int, std::strong_ordering>);
46static_assert(std::three_way_comparable<int, std::weak_ordering>);
47static_assert(std::three_way_comparable<double, std::partial_ordering>);
48static_assert(!std::three_way_comparable<double, std::weak_ordering>);
49static_assert(std::three_way_comparable<void*, std::strong_ordering>);
50static_assert(std::three_way_comparable<void*, std::weak_ordering>);
51static_assert(std::three_way_comparable<char*, std::strong_ordering>);
52static_assert(std::three_way_comparable<char*, std::weak_ordering>);
53static_assert(std::three_way_comparable<char const*, std::strong_ordering>);
54static_assert(std::three_way_comparable<char const*, std::weak_ordering>);
55static_assert(std::three_way_comparable<char volatile*, std::strong_ordering>);
56static_assert(std::three_way_comparable<char volatile*, std::weak_ordering>);
57static_assert(std::three_way_comparable<char const volatile*, std::strong_ordering>);
58static_assert(std::three_way_comparable<char const volatile*, std::weak_ordering>);
59static_assert(std::three_way_comparable<wchar_t&, std::strong_ordering>);
60static_assert(std::three_way_comparable<wchar_t&, std::weak_ordering>);
61static_assert(std::three_way_comparable<char8_t const&, std::strong_ordering>);
62static_assert(std::three_way_comparable<char8_t const&, std::weak_ordering>);
63static_assert(std::three_way_comparable<char16_t volatile&, std::strong_ordering>);
64static_assert(std::three_way_comparable<char16_t volatile&, std::weak_ordering>);
65static_assert(std::three_way_comparable<char32_t const volatile&, std::strong_ordering>);
66static_assert(std::three_way_comparable<char32_t const volatile&, std::weak_ordering>);
67static_assert(std::three_way_comparable<unsigned char&&, std::strong_ordering>);
68static_assert(std::three_way_comparable<unsigned char&&, std::weak_ordering>);
69static_assert(std::three_way_comparable<unsigned short const&&, std::strong_ordering>);
70static_assert(std::three_way_comparable<unsigned short const&&, std::weak_ordering>);
71static_assert(std::three_way_comparable<unsigned int volatile&&, std::strong_ordering>);
72static_assert(std::three_way_comparable<unsigned int volatile&&, std::weak_ordering>);
73static_assert(std::three_way_comparable<unsigned long const volatile&&, std::strong_ordering>);
74static_assert(std::three_way_comparable<unsigned long const volatile&&, std::weak_ordering>);
75
76static_assert(!std::three_way_comparable<int[5]>);
77static_assert(!std::three_way_comparable<int (*)(int)>);
78static_assert(!std::three_way_comparable<int (&)(int)>);
79static_assert(!std::three_way_comparable<int (*)(int) noexcept>);
80static_assert(!std::three_way_comparable<int (&)(int) noexcept>);
81static_assert(!std::three_way_comparable<std::nullptr_t>);
82static_assert(!std::three_way_comparable<void>);
83
84struct S {};
85static_assert(!std::three_way_comparable<int S::*>);
86static_assert(!std::three_way_comparable<int (S::*)()>);
87static_assert(!std::three_way_comparable<int (S::*)() noexcept>);
88static_assert(!std::three_way_comparable<int (S::*)() &>);
89static_assert(!std::three_way_comparable<int (S::*)() & noexcept>);
90static_assert(!std::three_way_comparable<int (S::*)() &&>);
91static_assert(!std::three_way_comparable<int (S::*)() && noexcept>);
92static_assert(!std::three_way_comparable<int (S::*)() const>);
93static_assert(!std::three_way_comparable<int (S::*)() const noexcept>);
94static_assert(!std::three_way_comparable<int (S::*)() const&>);
95static_assert(!std::three_way_comparable<int (S::*)() const & noexcept>);
96static_assert(!std::three_way_comparable<int (S::*)() const&&>);
97static_assert(!std::three_way_comparable<int (S::*)() const && noexcept>);
98static_assert(!std::three_way_comparable<int (S::*)() volatile>);
99static_assert(!std::three_way_comparable<int (S::*)() volatile noexcept>);
100static_assert(!std::three_way_comparable<int (S::*)() volatile&>);
101static_assert(!std::three_way_comparable<int (S::*)() volatile & noexcept>);
102static_assert(!std::three_way_comparable<int (S::*)() volatile&&>);
103static_assert(!std::three_way_comparable<int (S::*)() volatile && noexcept>);
104static_assert(!std::three_way_comparable<int (S::*)() const volatile>);
105static_assert(!std::three_way_comparable<int (S::*)() const volatile noexcept>);
106static_assert(!std::three_way_comparable<int (S::*)() const volatile&>);
107static_assert(!std::three_way_comparable<int (S::*)() const volatile & noexcept>);
108static_assert(!std::three_way_comparable<int (S::*)() const volatile&&>);
109static_assert(!std::three_way_comparable<int (S::*)() const volatile && noexcept>);
110} // namespace fundamentals
111
112namespace user_defined {
113
114struct S {
115 auto operator<=>(const S&) const = default;
116};
117
118static_assert(std::three_way_comparable<S>);
119static_assert(std::three_way_comparable<S, std::strong_ordering>);
120static_assert(std::three_way_comparable<S, std::partial_ordering>);
121
122struct SpaceshipNotDeclared {
123};
124
125static_assert(!std::three_way_comparable<SpaceshipNotDeclared>);
126
127struct SpaceshipDeleted {
128 auto operator<=>(const SpaceshipDeleted&) const = delete;
129};
130
131static_assert(!std::three_way_comparable<SpaceshipDeleted>);
132
133struct SpaceshipWithoutEqualityOperator {
134 auto operator<=>(const SpaceshipWithoutEqualityOperator&) const;
135};
136
137static_assert(!std::three_way_comparable<SpaceshipWithoutEqualityOperator>);
138
139struct EqualityOperatorDeleted {
140 bool operator==(const EqualityOperatorDeleted&) const = delete;
141};
142
143static_assert(!std::three_way_comparable<EqualityOperatorDeleted>);
144
145struct EqualityOperatorOnly {
146 bool operator==(const EqualityOperatorOnly&) const = default;
147};
148
149static_assert(!std::three_way_comparable<EqualityOperatorOnly>);
150
151struct SpaceshipDeclaredEqualityOperatorDeleted {
152 bool operator==(const SpaceshipDeclaredEqualityOperatorDeleted&) const = delete;
153 auto operator<=>(const SpaceshipDeclaredEqualityOperatorDeleted&) const = default;
154};
155
156static_assert(!std::three_way_comparable<SpaceshipDeclaredEqualityOperatorDeleted>);
157
158struct AllInequalityOperators {
159 bool operator<(const AllInequalityOperators&) const;
160 bool operator<=(const AllInequalityOperators&) const;
161 bool operator>(const AllInequalityOperators&) const;
162 bool operator>=(const AllInequalityOperators&) const;
163 bool operator!=(const AllInequalityOperators&) const;
164};
165
166static_assert(!std::three_way_comparable<AllInequalityOperators>);
167
168struct AllComparisonOperators {
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;
174 bool operator==(const AllComparisonOperators&) const;
175};
176
177static_assert(!std::three_way_comparable<AllComparisonOperators>);
178
179struct AllButOneInequalityOperators {
180 bool operator<(const AllButOneInequalityOperators&) const;
181 bool operator<=(const AllButOneInequalityOperators&) const;
182 bool operator>(const AllButOneInequalityOperators&) const;
183 bool operator!=(const AllButOneInequalityOperators&) const;
184};
185
186static_assert(!std::three_way_comparable<AllButOneInequalityOperators>);
187
188struct AllInequalityOperatorsOneDeleted {
189 bool operator<(const AllInequalityOperatorsOneDeleted&) const;
190 bool operator<=(const AllInequalityOperatorsOneDeleted&) const;
191 bool operator>(const AllInequalityOperatorsOneDeleted&) const;
192 bool operator>=(const AllInequalityOperatorsOneDeleted&) const = delete;
193 bool operator!=(const AllInequalityOperatorsOneDeleted&) const;
194};
195
196static_assert(!std::three_way_comparable<AllInequalityOperatorsOneDeleted>);
197
198struct EqualityOperatorWrongReturnType {
199 int operator==(const EqualityOperatorWrongReturnType&);
200 auto operator<=>(const EqualityOperatorWrongReturnType&) const = default;
201};
202
203static_assert(!std::three_way_comparable<EqualityOperatorWrongReturnType>);
204
205struct SpaceshipWrongReturnType {
206 bool operator==(const SpaceshipWrongReturnType&) const = default;
207 int operator<=>(const SpaceshipWrongReturnType&);
208};
209
210static_assert(!std::three_way_comparable<SpaceshipWrongReturnType>);
211
212struct EqualityOperatorNonConstArgument {
213 bool operator==(EqualityOperatorNonConstArgument&);
214 auto operator<=>(const EqualityOperatorNonConstArgument&) const = default;
215};
216
217static_assert(!std::three_way_comparable<EqualityOperatorNonConstArgument>);
218
219struct SpaceshipNonConstArgument {
220 bool operator==(const SpaceshipNonConstArgument&) const = default;
221 auto operator<=>(SpaceshipNonConstArgument&);
222};
223
224static_assert(!std::three_way_comparable<SpaceshipNonConstArgument>);
225} // namespace user_defined
226

source code of libcxx/test/std/language.support/cmp/cmp.concept/three_way_comparable.compile.pass.cpp