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// <functional>
10
11// template<class R, class T> constexpr unspecified mem_fn(R T::*) noexcept; // constexpr in C++20
12
13#include <functional>
14#include <cassert>
15#include <utility>
16#include <type_traits>
17
18#include "test_macros.h"
19
20struct A {
21 double data_;
22
23 TEST_CONSTEXPR_CXX14 char test0() { return 'a'; }
24 TEST_CONSTEXPR_CXX14 char test1(int) { return 'b'; }
25 TEST_CONSTEXPR_CXX14 char test2(int, double) { return 'c'; }
26
27 TEST_CONSTEXPR_CXX14 char test0_nothrow() TEST_NOEXCEPT { return 'd'; }
28 TEST_CONSTEXPR_CXX14 char test1_nothrow(int) TEST_NOEXCEPT { return 'e'; }
29 TEST_CONSTEXPR_CXX14 char test2_nothrow(int, double) TEST_NOEXCEPT { return 'f'; }
30
31 TEST_CONSTEXPR char test_c0() const { return 'a'; }
32 TEST_CONSTEXPR char test_c1(int) const { return 'b'; }
33 TEST_CONSTEXPR char test_c2(int, double) const { return 'c'; }
34
35 TEST_CONSTEXPR char test_c0_nothrow() const TEST_NOEXCEPT { return 'd'; }
36 TEST_CONSTEXPR char test_c1_nothrow(int) const TEST_NOEXCEPT { return 'e'; }
37 TEST_CONSTEXPR char test_c2_nothrow(int, double) const TEST_NOEXCEPT { return 'f'; }
38
39 char test_v0() volatile { return 'a'; }
40 char test_v1(int) volatile { return 'b'; }
41 char test_v2(int, double) volatile { return 'c'; }
42
43 char test_v0_nothrow() volatile TEST_NOEXCEPT { return 'd'; }
44 char test_v1_nothrow(int) volatile TEST_NOEXCEPT { return 'e'; }
45 char test_v2_nothrow(int, double) volatile TEST_NOEXCEPT { return 'f'; }
46
47 char test_cv0() const volatile { return 'a'; }
48 char test_cv1(int) const volatile { return 'b'; }
49 char test_cv2(int, double) const volatile { return 'c'; }
50
51 char test_cv0_nothrow() const volatile TEST_NOEXCEPT { return 'd'; }
52 char test_cv1_nothrow(int) const volatile TEST_NOEXCEPT { return 'e'; }
53 char test_cv2_nothrow(int, double) const volatile TEST_NOEXCEPT { return 'f'; }
54};
55
56template <class F>
57TEST_CONSTEXPR_CXX20 bool test_data(F f) {
58 A a = {.data_: 0.0};
59 f(a) = 5;
60 assert(a.data_ == 5);
61 A* ap = &a;
62 f(ap) = 6;
63 assert(a.data_ == 6);
64 const A* cap = ap;
65 assert(f(cap) == f(ap));
66 const F& cf = f;
67 assert(cf(ap) == f(ap));
68
69#if TEST_STD_VER >= 11
70 static_assert(noexcept(f(a)), "");
71 static_assert(noexcept(f(ap)), "");
72 static_assert(noexcept(f(cap)), "");
73 static_assert(noexcept(cf(ap)), "");
74#endif
75
76 return true;
77}
78
79template <class F>
80TEST_CONSTEXPR_CXX20 bool test_fun0(F f) {
81 A a = {};
82 assert(f(a) == 'a');
83 A* ap = &a;
84 assert(f(ap) == 'a');
85 const F& cf = f;
86 assert(cf(ap) == 'a');
87
88#if TEST_STD_VER >= 17
89 static_assert(!noexcept(f(a)), "");
90 static_assert(!noexcept(f(ap)), "");
91 static_assert(!noexcept(cf(ap)), "");
92#endif
93
94 return true;
95}
96
97template <class F>
98TEST_CONSTEXPR_CXX20 bool test_fun1(F f) {
99 A a = {};
100 assert(f(a, 1) == 'b');
101 A* ap = &a;
102 assert(f(ap, 2) == 'b');
103 const F& cf = f;
104 assert(cf(ap, 2) == 'b');
105
106#if TEST_STD_VER >= 17
107 static_assert(!noexcept(f(a, 0)), "");
108 static_assert(!noexcept(f(ap, 1)), "");
109 static_assert(!noexcept(cf(ap, 2)), "");
110#endif
111
112 return true;
113}
114
115template <class F>
116TEST_CONSTEXPR_CXX20 bool test_fun2(F f) {
117 A a = {};
118 assert(f(a, 1, 2) == 'c');
119 A* ap = &a;
120 assert(f(ap, 2, 3.5) == 'c');
121 const F& cf = f;
122 assert(cf(ap, 2, 3.5) == 'c');
123
124#if TEST_STD_VER >= 17
125 static_assert(!noexcept(f(a, 0, 0.0)), "");
126 static_assert(!noexcept(f(ap, 1, 2)), "");
127 static_assert(!noexcept(cf(ap, 2, 3.5)), "");
128#endif
129
130 return true;
131}
132
133template <class F>
134TEST_CONSTEXPR_CXX20 bool test_noexcept_fun0(F f) {
135 A a = {};
136 assert(f(a) == 'd');
137 A* ap = &a;
138 assert(f(ap) == 'd');
139 const F& cf = f;
140 assert(cf(ap) == 'd');
141
142#if TEST_STD_VER >= 17
143 static_assert(noexcept(f(a)), "");
144 static_assert(noexcept(f(ap)), "");
145 static_assert(noexcept(cf(ap)), "");
146#endif
147
148 return true;
149}
150
151template <class F>
152TEST_CONSTEXPR_CXX20 bool test_noexcept_fun1(F f) {
153 A a = {};
154 assert(f(a, 1) == 'e');
155 A* ap = &a;
156 assert(f(ap, 2) == 'e');
157 const F& cf = f;
158 assert(cf(ap, 2) == 'e');
159
160#if TEST_STD_VER >= 17
161 static_assert(noexcept(f(a, 0)), "");
162 static_assert(noexcept(f(ap, 1)), "");
163 static_assert(noexcept(cf(ap, 2)), "");
164#endif
165
166 return true;
167}
168
169template <class F>
170TEST_CONSTEXPR_CXX20 bool test_noexcept_fun2(F f) {
171 A a = {};
172 assert(f(a, 1, 2) == 'f');
173 A* ap = &a;
174 assert(f(ap, 2, 3.5) == 'f');
175 const F& cf = f;
176 assert(cf(ap, 2, 3.5) == 'f');
177
178#if TEST_STD_VER >= 17
179 static_assert(noexcept(f(a, 0, 0.0)), "");
180 static_assert(noexcept(f(ap, 1, 2)), "");
181 static_assert(noexcept(cf(ap, 2, 3.5)), "");
182#endif
183
184 return true;
185}
186
187template <class F>
188TEST_CONSTEXPR_CXX20 bool test_const_fun0(F f) {
189 A a = {};
190 assert(f(a) == 'a');
191 A* ap = &a;
192 assert(f(ap) == 'a');
193 const A* cap = &a;
194 assert(f(cap) == 'a');
195 const F& cf = f;
196 assert(cf(ap) == 'a');
197
198#if TEST_STD_VER >= 17
199 static_assert(!noexcept(f(a)), "");
200 static_assert(!noexcept(f(ap)), "");
201 static_assert(!noexcept(f(cap)), "");
202 static_assert(!noexcept(cf(ap)), "");
203#endif
204
205 return true;
206}
207
208template <class F>
209TEST_CONSTEXPR_CXX20 bool test_const_fun1(F f) {
210 A a = {};
211 assert(f(a, 1) == 'b');
212 A* ap = &a;
213 assert(f(ap, 2) == 'b');
214 const A* cap = &a;
215 assert(f(cap, 2) == 'b');
216 const F& cf = f;
217 assert(cf(ap, 2) == 'b');
218
219#if TEST_STD_VER >= 17
220 static_assert(!noexcept(f(a, 0)), "");
221 static_assert(!noexcept(f(ap, 1)), "");
222 static_assert(!noexcept(f(cap, 2)), "");
223 static_assert(!noexcept(cf(ap, 3)), "");
224#endif
225
226 return true;
227}
228
229template <class F>
230TEST_CONSTEXPR_CXX20 bool test_const_fun2(F f) {
231 A a = {};
232 assert(f(a, 1, 2) == 'c');
233 A* ap = &a;
234 assert(f(ap, 2, 3.5) == 'c');
235 const A* cap = &a;
236 assert(f(cap, 2, 3.5) == 'c');
237 const F& cf = f;
238 assert(cf(ap, 2, 3.5) == 'c');
239
240#if TEST_STD_VER >= 17
241 static_assert(!noexcept(f(a, 0, 0.0)), "");
242 static_assert(!noexcept(f(ap, 1, 2)), "");
243 static_assert(!noexcept(f(cap, 2, 3.5)), "");
244 static_assert(!noexcept(cf(ap, 3, 17.29)), "");
245#endif
246
247 return true;
248}
249
250template <class F>
251TEST_CONSTEXPR_CXX20 bool test_const_noexcept_fun0(F f) {
252 A a = {};
253 assert(f(a) == 'd');
254 A* ap = &a;
255 assert(f(ap) == 'd');
256 const A* cap = &a;
257 assert(f(cap) == 'd');
258 const F& cf = f;
259 assert(cf(ap) == 'd');
260
261#if TEST_STD_VER >= 17
262 static_assert(noexcept(f(a)), "");
263 static_assert(noexcept(f(ap)), "");
264 static_assert(noexcept(f(cap)), "");
265 static_assert(noexcept(cf(ap)), "");
266#endif
267
268 return true;
269}
270
271template <class F>
272TEST_CONSTEXPR_CXX20 bool test_const_noexcept_fun1(F f) {
273 A a = {};
274 assert(f(a, 1) == 'e');
275 A* ap = &a;
276 assert(f(ap, 2) == 'e');
277 const A* cap = &a;
278 assert(f(cap, 2) == 'e');
279 const F& cf = f;
280 assert(cf(ap, 2) == 'e');
281
282#if TEST_STD_VER >= 17
283 static_assert(noexcept(f(a, 0)), "");
284 static_assert(noexcept(f(ap, 1)), "");
285 static_assert(noexcept(f(cap, 2)), "");
286 static_assert(noexcept(cf(ap, 3)), "");
287#endif
288
289 return true;
290}
291
292template <class F>
293TEST_CONSTEXPR_CXX20 bool test_const_noexcept_fun2(F f) {
294 A a = {};
295 assert(f(a, 1, 2) == 'f');
296 A* ap = &a;
297 assert(f(ap, 2, 3.5) == 'f');
298 const A* cap = &a;
299 assert(f(cap, 2, 3.5) == 'f');
300 const F& cf = f;
301 assert(cf(ap, 2, 3.5) == 'f');
302
303#if TEST_STD_VER >= 17
304 static_assert(noexcept(f(a, 0, 0.0)), "");
305 static_assert(noexcept(f(ap, 1, 2)), "");
306 static_assert(noexcept(f(cap, 2, 3.5)), "");
307 static_assert(noexcept(cf(ap, 3, 17.29)), "");
308#endif
309
310 return true;
311}
312
313template <class F>
314void test_volatile_fun0(F f) {
315 A a = {};
316 assert(f(a) == 'a');
317 A* ap = &a;
318 assert(f(ap) == 'a');
319 volatile A* cap = &a;
320 assert(f(cap) == 'a');
321 const F& cf = f;
322 assert(cf(ap) == 'a');
323
324#if TEST_STD_VER >= 17
325 static_assert(!noexcept(f(a)), "");
326 static_assert(!noexcept(f(ap)), "");
327 static_assert(!noexcept(f(cap)), "");
328 static_assert(!noexcept(cf(ap)), "");
329#endif
330}
331
332template <class F>
333void test_volatile_fun1(F f) {
334 A a = {};
335 assert(f(a, 1) == 'b');
336 A* ap = &a;
337 assert(f(ap, 2) == 'b');
338 volatile A* cap = &a;
339 assert(f(cap, 2) == 'b');
340 const F& cf = f;
341 assert(cf(ap, 2) == 'b');
342
343#if TEST_STD_VER >= 17
344 static_assert(!noexcept(f(a, 0)), "");
345 static_assert(!noexcept(f(ap, 1)), "");
346 static_assert(!noexcept(f(cap, 2)), "");
347 static_assert(!noexcept(cf(ap, 3)), "");
348#endif
349}
350
351template <class F>
352void test_volatile_fun2(F f) {
353 A a = {};
354 assert(f(a, 1, 2) == 'c');
355 A* ap = &a;
356 assert(f(ap, 2, 3.5) == 'c');
357 volatile A* cap = &a;
358 assert(f(cap, 2, 3.5) == 'c');
359 const F& cf = f;
360 assert(cf(ap, 2, 3.5) == 'c');
361
362#if TEST_STD_VER >= 17
363 static_assert(!noexcept(f(a, 0, 0.0)), "");
364 static_assert(!noexcept(f(ap, 1, 2)), "");
365 static_assert(!noexcept(f(cap, 2, 3.5)), "");
366 static_assert(!noexcept(cf(ap, 3, 17.29)), "");
367#endif
368}
369
370template <class F>
371void test_volatile_noexcept_fun0(F f) {
372 A a = {};
373 assert(f(a) == 'd');
374 A* ap = &a;
375 assert(f(ap) == 'd');
376 volatile A* cap = &a;
377 assert(f(cap) == 'd');
378 const F& cf = f;
379 assert(cf(ap) == 'd');
380
381#if TEST_STD_VER >= 17
382 static_assert(noexcept(f(a)), "");
383 static_assert(noexcept(f(ap)), "");
384 static_assert(noexcept(f(cap)), "");
385 static_assert(noexcept(cf(ap)), "");
386#endif
387}
388
389template <class F>
390void test_volatile_noexcept_fun1(F f) {
391 A a = {};
392 assert(f(a, 1) == 'e');
393 A* ap = &a;
394 assert(f(ap, 2) == 'e');
395 volatile A* cap = &a;
396 assert(f(cap, 2) == 'e');
397 const F& cf = f;
398 assert(cf(ap, 2) == 'e');
399
400#if TEST_STD_VER >= 17
401 static_assert(noexcept(f(a, 0)), "");
402 static_assert(noexcept(f(ap, 1)), "");
403 static_assert(noexcept(f(cap, 2)), "");
404 static_assert(noexcept(cf(ap, 3)), "");
405#endif
406}
407
408template <class F>
409void test_volatile_noexcept_fun2(F f) {
410 A a = {};
411 assert(f(a, 1, 2) == 'f');
412 A* ap = &a;
413 assert(f(ap, 2, 3.5) == 'f');
414 volatile A* cap = &a;
415 assert(f(cap, 2, 3.5) == 'f');
416 const F& cf = f;
417 assert(cf(ap, 2, 3.5) == 'f');
418
419#if TEST_STD_VER >= 17
420 static_assert(noexcept(f(a, 0, 0.0)), "");
421 static_assert(noexcept(f(ap, 1, 2)), "");
422 static_assert(noexcept(f(cap, 2, 3.5)), "");
423 static_assert(noexcept(cf(ap, 3, 17.29)), "");
424#endif
425}
426
427template <class F>
428void test_const_volatile_fun0(F f) {
429 A a = {};
430 assert(f(a) == 'a');
431 A* ap = &a;
432 assert(f(ap) == 'a');
433 const volatile A* cap = &a;
434 assert(f(cap) == 'a');
435 const F& cf = f;
436 assert(cf(ap) == 'a');
437
438#if TEST_STD_VER >= 17
439 static_assert(!noexcept(f(a)), "");
440 static_assert(!noexcept(f(ap)), "");
441 static_assert(!noexcept(f(cap)), "");
442 static_assert(!noexcept(cf(ap)), "");
443#endif
444}
445
446template <class F>
447void test_const_volatile_fun1(F f) {
448 A a = {};
449 assert(f(a, 1) == 'b');
450 A* ap = &a;
451 assert(f(ap, 2) == 'b');
452 const volatile A* cap = &a;
453 assert(f(cap, 2) == 'b');
454 const F& cf = f;
455 assert(cf(ap, 2) == 'b');
456
457#if TEST_STD_VER >= 17
458 static_assert(!noexcept(f(a, 0)), "");
459 static_assert(!noexcept(f(ap, 1)), "");
460 static_assert(!noexcept(f(cap, 2)), "");
461 static_assert(!noexcept(cf(ap, 3)), "");
462#endif
463}
464
465template <class F>
466void test_const_volatile_fun2(F f) {
467 A a = {};
468 assert(f(a, 1, 2) == 'c');
469 A* ap = &a;
470 assert(f(ap, 2, 3.5) == 'c');
471 const volatile A* cap = &a;
472 assert(f(cap, 2, 3.5) == 'c');
473 const F& cf = f;
474 assert(cf(ap, 2, 3.5) == 'c');
475
476#if TEST_STD_VER >= 17
477 static_assert(!noexcept(f(a, 0, 0.0)), "");
478 static_assert(!noexcept(f(ap, 1, 2)), "");
479 static_assert(!noexcept(f(cap, 2, 3.5)), "");
480 static_assert(!noexcept(cf(ap, 3, 17.29)), "");
481#endif
482}
483
484template <class F>
485void test_const_volatile_noexcept_fun0(F f) {
486 A a = {};
487 assert(f(a) == 'd');
488 A* ap = &a;
489 assert(f(ap) == 'd');
490 const volatile A* cap = &a;
491 assert(f(cap) == 'd');
492 const F& cf = f;
493 assert(cf(ap) == 'd');
494
495#if TEST_STD_VER >= 17
496 static_assert(noexcept(f(a)), "");
497 static_assert(noexcept(f(ap)), "");
498 static_assert(noexcept(f(cap)), "");
499 static_assert(noexcept(cf(ap)), "");
500#endif
501}
502
503template <class F>
504void test_const_volatile_noexcept_fun1(F f) {
505 A a = {};
506 assert(f(a, 1) == 'e');
507 A* ap = &a;
508 assert(f(ap, 2) == 'e');
509 const volatile A* cap = &a;
510 assert(f(cap, 2) == 'e');
511 const F& cf = f;
512 assert(cf(ap, 2) == 'e');
513
514#if TEST_STD_VER >= 17
515 static_assert(noexcept(f(a, 0)), "");
516 static_assert(noexcept(f(ap, 1)), "");
517 static_assert(noexcept(f(cap, 2)), "");
518 static_assert(noexcept(cf(ap, 3)), "");
519#endif
520}
521
522template <class F>
523void test_const_volatile_noexcept_fun2(F f) {
524 A a = {};
525 assert(f(a, 1, 2) == 'f');
526 A* ap = &a;
527 assert(f(ap, 2, 3.5) == 'f');
528 const volatile A* cap = &a;
529 assert(f(cap, 2, 3.5) == 'f');
530 const F& cf = f;
531 assert(cf(ap, 2, 3.5) == 'f');
532
533#if TEST_STD_VER >= 17
534 static_assert(noexcept(f(a, 0, 0.0)), "");
535 static_assert(noexcept(f(ap, 1, 2)), "");
536 static_assert(noexcept(f(cap, 2, 3.5)), "");
537 static_assert(noexcept(cf(ap, 3, 17.29)), "");
538#endif
539}
540
541#if TEST_STD_VER >= 11
542template <class V, class Func, class... Args>
543struct is_callable_impl : std::false_type {};
544
545template <class Func, class... Args>
546struct is_callable_impl<decltype((void)std::declval<Func>()(std::declval<Args>()...)), Func, Args...> : std::true_type {
547};
548
549template <class Func, class... Args>
550struct is_callable : is_callable_impl<void, Func, Args...>::type {};
551
552template <class F>
553void test_sfinae_data(F) {
554 static_assert(is_callable<F, A>::value, "");
555 static_assert(is_callable<F, const A>::value, "");
556 static_assert(is_callable<F, A&>::value, "");
557 static_assert(is_callable<F, const A&>::value, "");
558 static_assert(is_callable<F, A*>::value, "");
559 static_assert(is_callable<F, const A*>::value, "");
560
561 static_assert(!is_callable<F, A, char>::value, "");
562 static_assert(!is_callable<F, const A, char>::value, "");
563 static_assert(!is_callable<F, A&, char>::value, "");
564 static_assert(!is_callable<F, const A&, char>::value, "");
565 static_assert(!is_callable<F, A*, char>::value, "");
566 static_assert(!is_callable<F, const A*, char>::value, "");
567}
568
569template <class F>
570void test_sfinae_fun0(F) {
571 static_assert(is_callable<F, A>::value, "");
572 static_assert(is_callable<F, A&>::value, "");
573 static_assert(is_callable<F, A*>::value, "");
574
575 static_assert(!is_callable<F, const A>::value, "");
576 static_assert(!is_callable<F, const A&>::value, "");
577 static_assert(!is_callable<F, const A*>::value, "");
578
579 static_assert(!is_callable<F, volatile A>::value, "");
580 static_assert(!is_callable<F, volatile A&>::value, "");
581 static_assert(!is_callable<F, volatile A*>::value, "");
582
583 static_assert(!is_callable<F, const volatile A>::value, "");
584 static_assert(!is_callable<F, const volatile A&>::value, "");
585 static_assert(!is_callable<F, const volatile A*>::value, "");
586
587 static_assert(!is_callable<F, A, int>::value, "");
588 static_assert(!is_callable<F, A&, int>::value, "");
589 static_assert(!is_callable<F, A*, int>::value, "");
590}
591
592template <class F>
593void test_sfinae_fun1(F) {
594 static_assert(is_callable<F, A, int>::value, "");
595 static_assert(is_callable<F, A&, int>::value, "");
596 static_assert(is_callable<F, A*, int>::value, "");
597
598 static_assert(!is_callable<F, A>::value, "");
599 static_assert(!is_callable<F, A&>::value, "");
600 static_assert(!is_callable<F, A*>::value, "");
601}
602
603template <class F>
604void test_sfinae_const_fun0(F) {
605 static_assert(is_callable<F, A>::value, "");
606 static_assert(is_callable<F, A&>::value, "");
607 static_assert(is_callable<F, A*>::value, "");
608
609 static_assert(is_callable<F, const A>::value, "");
610 static_assert(is_callable<F, const A&>::value, "");
611 static_assert(is_callable<F, const A*>::value, "");
612
613 static_assert(!is_callable<F, volatile A>::value, "");
614 static_assert(!is_callable<F, volatile A&>::value, "");
615 static_assert(!is_callable<F, volatile A*>::value, "");
616
617 static_assert(!is_callable<F, const volatile A>::value, "");
618 static_assert(!is_callable<F, const volatile A&>::value, "");
619 static_assert(!is_callable<F, const volatile A*>::value, "");
620}
621
622template <class F>
623void test_sfinae_volatile_fun0(F) {
624 static_assert(is_callable<F, A>::value, "");
625 static_assert(is_callable<F, A&>::value, "");
626 static_assert(is_callable<F, A*>::value, "");
627
628 static_assert(!is_callable<F, const A>::value, "");
629 static_assert(!is_callable<F, const A&>::value, "");
630 static_assert(!is_callable<F, const A*>::value, "");
631
632 static_assert(is_callable<F, volatile A>::value, "");
633 static_assert(is_callable<F, volatile A&>::value, "");
634 static_assert(is_callable<F, volatile A*>::value, "");
635
636 static_assert(!is_callable<F, const volatile A>::value, "");
637 static_assert(!is_callable<F, const volatile A&>::value, "");
638 static_assert(!is_callable<F, const volatile A*>::value, "");
639}
640
641template <class F>
642void test_sfinae_const_volatile_fun0(F) {
643 static_assert(is_callable<F, A>::value, "");
644 static_assert(is_callable<F, A&>::value, "");
645 static_assert(is_callable<F, A*>::value, "");
646
647 static_assert(is_callable<F, const A>::value, "");
648 static_assert(is_callable<F, const A&>::value, "");
649 static_assert(is_callable<F, const A*>::value, "");
650
651 static_assert(is_callable<F, volatile A>::value, "");
652 static_assert(is_callable<F, volatile A&>::value, "");
653 static_assert(is_callable<F, volatile A*>::value, "");
654
655 static_assert(is_callable<F, const volatile A>::value, "");
656 static_assert(is_callable<F, const volatile A&>::value, "");
657 static_assert(is_callable<F, const volatile A*>::value, "");
658}
659#endif
660
661int main(int, char**) {
662 test_data(std::mem_fn(pm: &A::data_));
663
664 test_fun0(std::mem_fn(&A::test0));
665 test_fun1(std::mem_fn(&A::test1));
666 test_fun2(std::mem_fn(&A::test2));
667
668 test_noexcept_fun0(std::mem_fn(&A::test0_nothrow));
669 test_noexcept_fun1(std::mem_fn(&A::test1_nothrow));
670 test_noexcept_fun2(std::mem_fn(&A::test2_nothrow));
671
672 test_const_fun0(std::mem_fn(&A::test_c0));
673 test_const_fun1(std::mem_fn(&A::test_c1));
674 test_const_fun2(std::mem_fn(&A::test_c2));
675
676 test_const_noexcept_fun0(std::mem_fn(&A::test_c0_nothrow));
677 test_const_noexcept_fun1(std::mem_fn(&A::test_c1_nothrow));
678 test_const_noexcept_fun2(std::mem_fn(&A::test_c2_nothrow));
679
680 test_volatile_fun0(std::mem_fn(&A::test_v0));
681 test_volatile_fun1(std::mem_fn(&A::test_v1));
682 test_volatile_fun2(std::mem_fn(&A::test_v2));
683
684 test_volatile_noexcept_fun0(std::mem_fn(&A::test_v0_nothrow));
685 test_volatile_noexcept_fun1(std::mem_fn(&A::test_v1_nothrow));
686 test_volatile_noexcept_fun2(std::mem_fn(&A::test_v2_nothrow));
687
688 test_const_volatile_fun0(std::mem_fn(&A::test_cv0));
689 test_const_volatile_fun1(std::mem_fn(&A::test_cv1));
690 test_const_volatile_fun2(std::mem_fn(&A::test_cv2));
691
692 test_const_volatile_noexcept_fun0(std::mem_fn(&A::test_cv0_nothrow));
693 test_const_volatile_noexcept_fun1(std::mem_fn(&A::test_cv1_nothrow));
694 test_const_volatile_noexcept_fun2(std::mem_fn(&A::test_cv2_nothrow));
695
696#if TEST_STD_VER >= 11
697 // LWG2489
698 static_assert((noexcept(std::mem_fn(&A::data_))), "");
699 static_assert((noexcept(std::mem_fn(&A::test0))), "");
700 static_assert((noexcept(std::mem_fn(&A::test0_nothrow))), "");
701
702 test_sfinae_data(std::mem_fn(&A::data_));
703
704 test_sfinae_fun0(std::mem_fn(&A::test0));
705 test_sfinae_fun0(std::mem_fn(&A::test0_nothrow));
706
707 test_sfinae_const_fun0(std::mem_fn(&A::test_c0));
708 test_sfinae_const_fun0(std::mem_fn(&A::test_c0_nothrow));
709
710 test_sfinae_volatile_fun0(std::mem_fn(&A::test_v0));
711 test_sfinae_volatile_fun0(std::mem_fn(&A::test_v0_nothrow));
712
713 test_sfinae_const_volatile_fun0(std::mem_fn(&A::test_cv0));
714 test_sfinae_const_volatile_fun0(std::mem_fn(&A::test_cv0_nothrow));
715
716 test_sfinae_fun1(std::mem_fn(&A::test1));
717 test_sfinae_fun1(std::mem_fn(&A::test1_nothrow));
718#endif
719
720#if TEST_STD_VER >= 20
721 static_assert(test_data(std::mem_fn(&A::data_)));
722
723 static_assert(test_fun0(std::mem_fn(&A::test0)));
724 static_assert(test_fun1(std::mem_fn(&A::test1)));
725 static_assert(test_fun2(std::mem_fn(&A::test2)));
726
727 static_assert(test_const_fun0(std::mem_fn(&A::test_c0)));
728 static_assert(test_const_fun1(std::mem_fn(&A::test_c1)));
729 static_assert(test_const_fun2(std::mem_fn(&A::test_c2)));
730
731 static_assert(test_noexcept_fun0(std::mem_fn(&A::test0_nothrow)));
732 static_assert(test_noexcept_fun1(std::mem_fn(&A::test1_nothrow)));
733 static_assert(test_noexcept_fun2(std::mem_fn(&A::test2_nothrow)));
734
735 static_assert(test_const_noexcept_fun0(std::mem_fn(&A::test_c0_nothrow)));
736 static_assert(test_const_noexcept_fun1(std::mem_fn(&A::test_c1_nothrow)));
737 static_assert(test_const_noexcept_fun2(std::mem_fn(&A::test_c2_nothrow)));
738#endif
739
740 return 0;
741}
742

source code of libcxx/test/std/utilities/function.objects/func.memfn/mem_fn.pass.cpp