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