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> |
12 | // concept totally_ordered; |
13 | |
14 | #include <concepts> |
15 | |
16 | #include <array> |
17 | #include <deque> |
18 | #include <forward_list> |
19 | #include <list> |
20 | #include <map> |
21 | #include <memory> |
22 | #include <optional> |
23 | #include <set> |
24 | #include <unordered_map> |
25 | #include <unordered_set> |
26 | #include <vector> |
27 | |
28 | #include "compare_types.h" |
29 | #include "test_macros.h" |
30 | |
31 | // `models_totally_ordered` checks that `std::totally_ordered` subsumes |
32 | // `std::equality_comparable`. This overload should *never* be called. |
33 | template <std::equality_comparable T> |
34 | constexpr bool models_totally_ordered() noexcept { |
35 | return false; |
36 | } |
37 | |
38 | template <std::totally_ordered T> |
39 | constexpr bool models_totally_ordered() noexcept { |
40 | return true; |
41 | } |
42 | |
43 | namespace fundamentals { |
44 | static_assert(models_totally_ordered<int>()); |
45 | static_assert(models_totally_ordered<double>()); |
46 | static_assert(models_totally_ordered<void*>()); |
47 | static_assert(models_totally_ordered<char*>()); |
48 | static_assert(models_totally_ordered<char const*>()); |
49 | static_assert(models_totally_ordered<char volatile*>()); |
50 | static_assert(models_totally_ordered<char const volatile*>()); |
51 | static_assert(models_totally_ordered<wchar_t&>()); |
52 | static_assert(models_totally_ordered<char8_t const&>()); |
53 | static_assert(models_totally_ordered<char16_t volatile&>()); |
54 | static_assert(models_totally_ordered<char32_t const volatile&>()); |
55 | static_assert(models_totally_ordered<unsigned char&&>()); |
56 | static_assert(models_totally_ordered<unsigned short const&&>()); |
57 | static_assert(models_totally_ordered<unsigned int volatile&&>()); |
58 | static_assert(models_totally_ordered<unsigned long const volatile&&>()); |
59 | static_assert(models_totally_ordered<int[5]>()); |
60 | static_assert(models_totally_ordered<int (*)(int)>()); |
61 | static_assert(models_totally_ordered<int (&)(int)>()); |
62 | static_assert(models_totally_ordered<int (*)(int) noexcept>()); |
63 | static_assert(models_totally_ordered<int (&)(int) noexcept>()); |
64 | |
65 | #ifndef TEST_COMPILER_GCC |
66 | static_assert(!std::totally_ordered<std::nullptr_t>); |
67 | #endif |
68 | |
69 | struct S {}; |
70 | static_assert(!std::totally_ordered<S>); |
71 | static_assert(!std::totally_ordered<int S::*>); |
72 | static_assert(!std::totally_ordered<int (S::*)()>); |
73 | static_assert(!std::totally_ordered<int (S::*)() noexcept>); |
74 | static_assert(!std::totally_ordered<int (S::*)() &>); |
75 | static_assert(!std::totally_ordered<int (S::*)() & noexcept>); |
76 | static_assert(!std::totally_ordered<int (S::*)() &&>); |
77 | static_assert(!std::totally_ordered < int (S::*)() && noexcept >); |
78 | static_assert(!std::totally_ordered<int (S::*)() const>); |
79 | static_assert(!std::totally_ordered<int (S::*)() const noexcept>); |
80 | static_assert(!std::totally_ordered<int (S::*)() const&>); |
81 | static_assert(!std::totally_ordered<int (S::*)() const & noexcept>); |
82 | static_assert(!std::totally_ordered<int (S::*)() const&&>); |
83 | static_assert(!std::totally_ordered < int (S::*)() const&& noexcept >); |
84 | static_assert(!std::totally_ordered<int (S::*)() volatile>); |
85 | static_assert(!std::totally_ordered<int (S::*)() volatile noexcept>); |
86 | static_assert(!std::totally_ordered<int (S::*)() volatile&>); |
87 | static_assert(!std::totally_ordered<int (S::*)() volatile & noexcept>); |
88 | static_assert(!std::totally_ordered<int (S::*)() volatile&&>); |
89 | static_assert(!std::totally_ordered < int (S::*)() volatile&& noexcept >); |
90 | static_assert(!std::totally_ordered<int (S::*)() const volatile>); |
91 | static_assert(!std::totally_ordered<int (S::*)() const volatile noexcept>); |
92 | static_assert(!std::totally_ordered<int (S::*)() const volatile&>); |
93 | static_assert(!std::totally_ordered<int (S::*)() const volatile & noexcept>); |
94 | static_assert(!std::totally_ordered<int (S::*)() const volatile&&>); |
95 | static_assert(!std::totally_ordered < int (S::*)() const volatile&& noexcept >); |
96 | |
97 | static_assert(!std::totally_ordered<void>); |
98 | } // namespace fundamentals |
99 | |
100 | namespace standard_types { |
101 | static_assert(models_totally_ordered<std::array<int, 10> >()); |
102 | static_assert(models_totally_ordered<std::deque<int> >()); |
103 | static_assert(models_totally_ordered<std::forward_list<int> >()); |
104 | static_assert(models_totally_ordered<std::list<int> >()); |
105 | static_assert(models_totally_ordered<std::optional<int> >()); |
106 | static_assert(models_totally_ordered<std::set<int> >()); |
107 | static_assert(models_totally_ordered<std::vector<bool> >()); |
108 | static_assert(models_totally_ordered<std::vector<int> >()); |
109 | |
110 | static_assert(!std::totally_ordered<std::unordered_map<int, void*> >); |
111 | static_assert(!std::totally_ordered<std::unordered_set<int> >); |
112 | |
113 | struct A {}; |
114 | // FIXME(cjdb): uncomment when operator<=> is implemented for each of these types. |
115 | // static_assert(!std::totally_ordered<std::array<A, 10> >); |
116 | // static_assert(!std::totally_ordered<std::deque<A> >); |
117 | // static_assert(!std::totally_ordered<std::forward_list<A> >); |
118 | // static_assert(!std::totally_ordered<std::list<A> >); |
119 | // static_assert(!std::totally_ordered<std::set<A> >); |
120 | // static_assert(!std::totally_ordered<std::vector<A> >); |
121 | } // namespace standard_types |
122 | |
123 | namespace types_fit_for_purpose { |
124 | static_assert(models_totally_ordered<member_three_way_comparable>()); |
125 | static_assert(models_totally_ordered<friend_three_way_comparable>()); |
126 | static_assert(models_totally_ordered<explicit_operators>()); |
127 | static_assert(models_totally_ordered<different_return_types>()); |
128 | static_assert(!std::totally_ordered<cxx20_member_eq>); |
129 | static_assert(!std::totally_ordered<cxx20_friend_eq>); |
130 | static_assert(!std::totally_ordered<one_member_one_friend>); |
131 | static_assert(!std::totally_ordered<equality_comparable_with_ec1>); |
132 | |
133 | static_assert(!std::totally_ordered<no_eq>); |
134 | static_assert(!std::totally_ordered<no_neq>); |
135 | static_assert(!std::totally_ordered<no_lt>); |
136 | static_assert(!std::totally_ordered<no_gt>); |
137 | static_assert(!std::totally_ordered<no_le>); |
138 | static_assert(!std::totally_ordered<no_ge>); |
139 | |
140 | static_assert(!std::totally_ordered<wrong_return_type_eq>); |
141 | static_assert(!std::totally_ordered<wrong_return_type_ne>); |
142 | static_assert(!std::totally_ordered<wrong_return_type_lt>); |
143 | static_assert(!std::totally_ordered<wrong_return_type_gt>); |
144 | static_assert(!std::totally_ordered<wrong_return_type_le>); |
145 | static_assert(!std::totally_ordered<wrong_return_type_ge>); |
146 | static_assert(!std::totally_ordered<wrong_return_type>); |
147 | |
148 | static_assert(!std::totally_ordered<cxx20_member_eq_operator_with_deleted_ne>); |
149 | static_assert(!std::totally_ordered<cxx20_friend_eq_operator_with_deleted_ne>); |
150 | static_assert( |
151 | !std::totally_ordered<member_three_way_comparable_with_deleted_eq>); |
152 | static_assert( |
153 | !std::totally_ordered<member_three_way_comparable_with_deleted_ne>); |
154 | static_assert( |
155 | !std::totally_ordered<friend_three_way_comparable_with_deleted_eq>); |
156 | static_assert( |
157 | !std::totally_ordered<friend_three_way_comparable_with_deleted_ne>); |
158 | |
159 | static_assert(!std::totally_ordered<eq_returns_explicit_bool>); |
160 | static_assert(!std::totally_ordered<ne_returns_explicit_bool>); |
161 | static_assert(!std::totally_ordered<lt_returns_explicit_bool>); |
162 | static_assert(!std::totally_ordered<gt_returns_explicit_bool>); |
163 | static_assert(!std::totally_ordered<le_returns_explicit_bool>); |
164 | static_assert(!std::totally_ordered<ge_returns_explicit_bool>); |
165 | static_assert(std::totally_ordered<returns_true_type>); |
166 | static_assert(std::totally_ordered<returns_int_ptr>); |
167 | |
168 | static_assert(std::totally_ordered<partial_ordering_totally_ordered_with>); |
169 | static_assert(std::totally_ordered<weak_ordering_totally_ordered_with>); |
170 | static_assert(std::totally_ordered<strong_ordering_totally_ordered_with>); |
171 | } // namespace types_fit_for_purpose |
172 | |
173 | int main(int, char**) { return 0; } |
174 | |