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 | // type_traits |
10 | |
11 | // member_function_pointer |
12 | |
13 | #include <type_traits> |
14 | #include "test_macros.h" |
15 | |
16 | // NOTE: On Windows the function `test_is_member_function<void()>` and |
17 | // `test_is_member_function<void() noexcept> has the same mangled despite being |
18 | // a distinct instantiation. This causes Clang to emit an error. However |
19 | // structs do not have this problem. |
20 | template <class T> |
21 | struct test_member_function_pointer_imp { |
22 | static_assert(!std::is_void<T>::value, "" ); |
23 | #if TEST_STD_VER > 11 |
24 | static_assert(!std::is_null_pointer<T>::value, "" ); |
25 | #endif |
26 | static_assert(!std::is_integral<T>::value, "" ); |
27 | static_assert(!std::is_floating_point<T>::value, "" ); |
28 | static_assert(!std::is_array<T>::value, "" ); |
29 | static_assert(!std::is_pointer<T>::value, "" ); |
30 | static_assert(!std::is_lvalue_reference<T>::value, "" ); |
31 | static_assert(!std::is_rvalue_reference<T>::value, "" ); |
32 | static_assert(!std::is_member_object_pointer<T>::value, "" ); |
33 | static_assert( std::is_member_function_pointer<T>::value, "" ); |
34 | static_assert(!std::is_enum<T>::value, "" ); |
35 | static_assert(!std::is_union<T>::value, "" ); |
36 | static_assert(!std::is_class<T>::value, "" ); |
37 | static_assert(!std::is_function<T>::value, "" ); |
38 | }; |
39 | |
40 | template <class T> |
41 | struct test_member_function_pointer : |
42 | test_member_function_pointer_imp<T>, |
43 | test_member_function_pointer_imp<const T>, |
44 | test_member_function_pointer_imp<volatile T>, |
45 | test_member_function_pointer_imp<const volatile T> |
46 | { |
47 | }; |
48 | |
49 | class Class |
50 | { |
51 | }; |
52 | |
53 | struct incomplete_type; |
54 | |
55 | int main(int, char**) |
56 | { |
57 | test_member_function_pointer<void (Class::*)()>(); |
58 | test_member_function_pointer<void (Class::*)(int)>(); |
59 | test_member_function_pointer<void (Class::*)(int, char)>(); |
60 | |
61 | test_member_function_pointer<void (Class::*)() const>(); |
62 | test_member_function_pointer<void (Class::*)(int) const>(); |
63 | test_member_function_pointer<void (Class::*)(int, char) const>(); |
64 | |
65 | test_member_function_pointer<void (Class::*)() volatile>(); |
66 | test_member_function_pointer<void (Class::*)(int) volatile>(); |
67 | test_member_function_pointer<void (Class::*)(int, char) volatile>(); |
68 | |
69 | test_member_function_pointer<void (Class::*)(...)>(); |
70 | test_member_function_pointer<void (Class::*)(int, ...)>(); |
71 | test_member_function_pointer<void (Class::*)(int, char, ...)>(); |
72 | |
73 | test_member_function_pointer<void (Class::*)(...) const>(); |
74 | test_member_function_pointer<void (Class::*)(int, ...) const>(); |
75 | test_member_function_pointer<void (Class::*)(int, char, ...) const>(); |
76 | |
77 | test_member_function_pointer<void (Class::*)(...) volatile>(); |
78 | test_member_function_pointer<void (Class::*)(int, ...) volatile>(); |
79 | test_member_function_pointer<void (Class::*)(int, char, ...) volatile>(); |
80 | |
81 | |
82 | // reference qualifiers on functions are a C++11 extension |
83 | #if TEST_STD_VER >= 11 |
84 | // Noexcept qualifiers |
85 | test_member_function_pointer<void (Class::*)() noexcept>(); |
86 | test_member_function_pointer<void (Class::*)(int) noexcept>(); |
87 | test_member_function_pointer<void (Class::*)(int, char) noexcept>(); |
88 | |
89 | test_member_function_pointer<void (Class::*)() const noexcept>(); |
90 | test_member_function_pointer<void (Class::*)(int) const noexcept>(); |
91 | test_member_function_pointer<void (Class::*)(int, char) const noexcept>(); |
92 | |
93 | test_member_function_pointer<void (Class::*)() volatile noexcept>(); |
94 | test_member_function_pointer<void (Class::*)(int) volatile noexcept>(); |
95 | test_member_function_pointer<void (Class::*)(int, char) volatile noexcept>(); |
96 | |
97 | test_member_function_pointer<void (Class::*)(...) noexcept>(); |
98 | test_member_function_pointer<void (Class::*)(int, ...) noexcept>(); |
99 | test_member_function_pointer<void (Class::*)(int, char, ...) noexcept>(); |
100 | |
101 | test_member_function_pointer<void (Class::*)(...) const noexcept>(); |
102 | test_member_function_pointer<void (Class::*)(int, ...) const noexcept>(); |
103 | test_member_function_pointer<void (Class::*)(int, char, ...) const noexcept>(); |
104 | |
105 | test_member_function_pointer<void (Class::*)(...) volatile noexcept>(); |
106 | test_member_function_pointer<void (Class::*)(int, ...) volatile noexcept>(); |
107 | test_member_function_pointer<void (Class::*)(int, char, ...) volatile noexcept>(); |
108 | |
109 | // lvalue qualifiers |
110 | test_member_function_pointer<void (Class::*)() &>(); |
111 | test_member_function_pointer<void (Class::*)(int) &>(); |
112 | test_member_function_pointer<void (Class::*)(int, char) &>(); |
113 | test_member_function_pointer<void (Class::*)(...) &>(); |
114 | test_member_function_pointer<void (Class::*)(int,...) &>(); |
115 | test_member_function_pointer<void (Class::*)(int, char,...) &>(); |
116 | |
117 | test_member_function_pointer<void (Class::*)() const &>(); |
118 | test_member_function_pointer<void (Class::*)(int) const &>(); |
119 | test_member_function_pointer<void (Class::*)(int, char) const &>(); |
120 | test_member_function_pointer<void (Class::*)(...) const &>(); |
121 | test_member_function_pointer<void (Class::*)(int,...) const &>(); |
122 | test_member_function_pointer<void (Class::*)(int, char,...) const &>(); |
123 | |
124 | test_member_function_pointer<void (Class::*)() volatile &>(); |
125 | test_member_function_pointer<void (Class::*)(int) volatile &>(); |
126 | test_member_function_pointer<void (Class::*)(int, char) volatile &>(); |
127 | test_member_function_pointer<void (Class::*)(...) volatile &>(); |
128 | test_member_function_pointer<void (Class::*)(int,...) volatile &>(); |
129 | test_member_function_pointer<void (Class::*)(int, char,...) volatile &>(); |
130 | |
131 | test_member_function_pointer<void (Class::*)() const volatile &>(); |
132 | test_member_function_pointer<void (Class::*)(int) const volatile &>(); |
133 | test_member_function_pointer<void (Class::*)(int, char) const volatile &>(); |
134 | test_member_function_pointer<void (Class::*)(...) const volatile &>(); |
135 | test_member_function_pointer<void (Class::*)(int,...) const volatile &>(); |
136 | test_member_function_pointer<void (Class::*)(int, char,...) const volatile &>(); |
137 | |
138 | // Lvalue qualifiers with noexcept |
139 | test_member_function_pointer<void (Class::*)() & noexcept>(); |
140 | test_member_function_pointer<void (Class::*)(int) & noexcept>(); |
141 | test_member_function_pointer<void (Class::*)(int, char) & noexcept>(); |
142 | test_member_function_pointer<void (Class::*)(...) & noexcept>(); |
143 | test_member_function_pointer<void (Class::*)(int,...) & noexcept>(); |
144 | test_member_function_pointer<void (Class::*)(int, char,...) & noexcept>(); |
145 | |
146 | test_member_function_pointer<void (Class::*)() const & noexcept>(); |
147 | test_member_function_pointer<void (Class::*)(int) const & noexcept>(); |
148 | test_member_function_pointer<void (Class::*)(int, char) const & noexcept>(); |
149 | test_member_function_pointer<void (Class::*)(...) const & noexcept>(); |
150 | test_member_function_pointer<void (Class::*)(int,...) const & noexcept>(); |
151 | test_member_function_pointer<void (Class::*)(int, char,...) const & noexcept>(); |
152 | |
153 | test_member_function_pointer<void (Class::*)() volatile & noexcept>(); |
154 | test_member_function_pointer<void (Class::*)(int) volatile & noexcept>(); |
155 | test_member_function_pointer<void (Class::*)(int, char) volatile & noexcept>(); |
156 | test_member_function_pointer<void (Class::*)(...) volatile & noexcept>(); |
157 | test_member_function_pointer<void (Class::*)(int,...) volatile & noexcept>(); |
158 | test_member_function_pointer<void (Class::*)(int, char,...) volatile & noexcept>(); |
159 | |
160 | test_member_function_pointer<void (Class::*)() const volatile & noexcept>(); |
161 | test_member_function_pointer<void (Class::*)(int) const volatile & noexcept>(); |
162 | test_member_function_pointer<void (Class::*)(int, char) const volatile & noexcept>(); |
163 | test_member_function_pointer<void (Class::*)(...) const volatile & noexcept>(); |
164 | test_member_function_pointer<void (Class::*)(int,...) const volatile & noexcept>(); |
165 | test_member_function_pointer<void (Class::*)(int, char,...) const volatile & noexcept>(); |
166 | |
167 | // RValue qualifiers |
168 | test_member_function_pointer<void (Class::*)() &&>(); |
169 | test_member_function_pointer<void (Class::*)(int) &&>(); |
170 | test_member_function_pointer<void (Class::*)(int, char) &&>(); |
171 | test_member_function_pointer<void (Class::*)(...) &&>(); |
172 | test_member_function_pointer<void (Class::*)(int,...) &&>(); |
173 | test_member_function_pointer<void (Class::*)(int, char,...) &&>(); |
174 | |
175 | test_member_function_pointer<void (Class::*)() const &&>(); |
176 | test_member_function_pointer<void (Class::*)(int) const &&>(); |
177 | test_member_function_pointer<void (Class::*)(int, char) const &&>(); |
178 | test_member_function_pointer<void (Class::*)(...) const &&>(); |
179 | test_member_function_pointer<void (Class::*)(int,...) const &&>(); |
180 | test_member_function_pointer<void (Class::*)(int, char,...) const &&>(); |
181 | |
182 | test_member_function_pointer<void (Class::*)() volatile &&>(); |
183 | test_member_function_pointer<void (Class::*)(int) volatile &&>(); |
184 | test_member_function_pointer<void (Class::*)(int, char) volatile &&>(); |
185 | test_member_function_pointer<void (Class::*)(...) volatile &&>(); |
186 | test_member_function_pointer<void (Class::*)(int,...) volatile &&>(); |
187 | test_member_function_pointer<void (Class::*)(int, char,...) volatile &&>(); |
188 | |
189 | test_member_function_pointer<void (Class::*)() const volatile &&>(); |
190 | test_member_function_pointer<void (Class::*)(int) const volatile &&>(); |
191 | test_member_function_pointer<void (Class::*)(int, char) const volatile &&>(); |
192 | test_member_function_pointer<void (Class::*)(...) const volatile &&>(); |
193 | test_member_function_pointer<void (Class::*)(int,...) const volatile &&>(); |
194 | test_member_function_pointer<void (Class::*)(int, char,...) const volatile &&>(); |
195 | |
196 | // RValue qualifiers with noexcept |
197 | test_member_function_pointer<void (Class::*)() && noexcept>(); |
198 | test_member_function_pointer<void (Class::*)(int) && noexcept>(); |
199 | test_member_function_pointer<void (Class::*)(int, char) && noexcept>(); |
200 | test_member_function_pointer<void (Class::*)(...) && noexcept>(); |
201 | test_member_function_pointer<void (Class::*)(int,...) && noexcept>(); |
202 | test_member_function_pointer<void (Class::*)(int, char,...) && noexcept>(); |
203 | |
204 | test_member_function_pointer<void (Class::*)() const && noexcept>(); |
205 | test_member_function_pointer<void (Class::*)(int) const && noexcept>(); |
206 | test_member_function_pointer<void (Class::*)(int, char) const && noexcept>(); |
207 | test_member_function_pointer<void (Class::*)(...) const && noexcept>(); |
208 | test_member_function_pointer<void (Class::*)(int,...) const && noexcept>(); |
209 | test_member_function_pointer<void (Class::*)(int, char,...) const && noexcept>(); |
210 | |
211 | test_member_function_pointer<void (Class::*)() volatile && noexcept>(); |
212 | test_member_function_pointer<void (Class::*)(int) volatile && noexcept>(); |
213 | test_member_function_pointer<void (Class::*)(int, char) volatile && noexcept>(); |
214 | test_member_function_pointer<void (Class::*)(...) volatile && noexcept>(); |
215 | test_member_function_pointer<void (Class::*)(int,...) volatile && noexcept>(); |
216 | test_member_function_pointer<void (Class::*)(int, char,...) volatile && noexcept>(); |
217 | |
218 | test_member_function_pointer<void (Class::*)() const volatile && noexcept>(); |
219 | test_member_function_pointer<void (Class::*)(int) const volatile && noexcept>(); |
220 | test_member_function_pointer<void (Class::*)(int, char) const volatile && noexcept>(); |
221 | test_member_function_pointer<void (Class::*)(...) const volatile && noexcept>(); |
222 | test_member_function_pointer<void (Class::*)(int,...) const volatile && noexcept>(); |
223 | test_member_function_pointer<void (Class::*)(int, char,...) const volatile && noexcept>(); |
224 | #endif |
225 | |
226 | // LWG#2582 |
227 | static_assert(!std::is_member_function_pointer<incomplete_type>::value, "" ); |
228 | |
229 | return 0; |
230 | } |
231 | |