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

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