xref: /llvm-project/libcxx/test/std/utilities/function.objects/func.memfn/mem_fn.pass.cpp (revision a061d4d5cedf8f4651a01ea2e8cf98bd8863bf0f)
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 
20 struct 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 
56 template <class F>
57 TEST_CONSTEXPR_CXX20 bool test_data(F f) {
58   A a  = {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 
79 template <class F>
80 TEST_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 
97 template <class F>
98 TEST_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 
115 template <class F>
116 TEST_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 
133 template <class F>
134 TEST_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 
151 template <class F>
152 TEST_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 
169 template <class F>
170 TEST_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 
187 template <class F>
188 TEST_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 
208 template <class F>
209 TEST_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 
229 template <class F>
230 TEST_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 
250 template <class F>
251 TEST_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 
271 template <class F>
272 TEST_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 
292 template <class F>
293 TEST_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 
313 template <class F>
314 void 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 
332 template <class F>
333 void 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 
351 template <class F>
352 void 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 
370 template <class F>
371 void 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 
389 template <class F>
390 void 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 
408 template <class F>
409 void 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 
427 template <class F>
428 void 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 
446 template <class F>
447 void 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 
465 template <class F>
466 void 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 
484 template <class F>
485 void 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 
503 template <class F>
504 void 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 
522 template <class F>
523 void 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
542 template <class V, class Func, class... Args>
543 struct is_callable_impl : std::false_type {};
544 
545 template <class Func, class... Args>
546 struct is_callable_impl<decltype((void)std::declval<Func>()(std::declval<Args>()...)), Func, Args...> : std::true_type {
547 };
548 
549 template <class Func, class... Args>
550 struct is_callable : is_callable_impl<void, Func, Args...>::type {};
551 
552 template <class F>
553 void 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 
569 template <class F>
570 void 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 
592 template <class F>
593 void 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 
603 template <class F>
604 void 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 
622 template <class F>
623 void 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 
641 template <class F>
642 void 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 
661 int main(int, char**) {
662   test_data(std::mem_fn(&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