xref: /llvm-project/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.pass.cpp (revision 76804e89b34333e52c8000efc44217ccd4fd7fca)
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 // reference_wrapper
12 
13 //  template <class... ArgTypes>
14 //    constexpr typename result_of<T&(ArgTypes&&...)>::type               // constexpr since C++20
15 //        operator() (ArgTypes&&...) const
16 //            noexcept(is_nothrow_invocable_v<T&, ArgTypes...>);          // noexcept since C++17
17 
18 #include <functional>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 
23 #if TEST_STD_VER > 14
24 #  define INVOKE_NOEXCEPT(expected, ...) static_assert(noexcept(__VA_ARGS__) == expected)
25 #else
26 #  define INVOKE_NOEXCEPT(expected, ...)
27 #endif
28 
29 int count = 0;
30 
31 // 1 arg, return void
32 
f_void_1(int i)33 void f_void_1(int i)
34 {
35     count += i;
36 }
37 
38 struct A_void_1
39 {
operator ()A_void_140     void operator()(int i)
41     {
42         count += i;
43     }
44 
mem1A_void_145     void mem1() {++count;}
mem2A_void_146     void mem2() const {++count;}
47 };
48 
49 void
test_void_1()50 test_void_1()
51 {
52     int save_count = count;
53     // function
54     {
55     std::reference_wrapper<void (int)> r1(f_void_1);
56     int i = 2;
57     r1(i);
58     INVOKE_NOEXCEPT(false, r1(i));
59     assert(count == save_count+2);
60     save_count = count;
61     }
62     // function pointer
63     {
64     void (*fp)(int) = f_void_1;
65     std::reference_wrapper<void (*)(int)> r1(fp);
66     int i = 3;
67     r1(i);
68     INVOKE_NOEXCEPT(false, r1(i));
69     assert(count == save_count+3);
70     save_count = count;
71     }
72     // functor
73     {
74     A_void_1 a0;
75     std::reference_wrapper<A_void_1> r1(a0);
76     int i = 4;
77     r1(i);
78     INVOKE_NOEXCEPT(false, r1(i));
79     assert(count == save_count+4);
80     save_count = count;
81     }
82     // member function pointer
83     {
84     void (A_void_1::*fp)() = &A_void_1::mem1;
85     std::reference_wrapper<void (A_void_1::*)()> r1(fp);
86     A_void_1 a;
87     r1(a);
88     INVOKE_NOEXCEPT(false, r1(a));
89     assert(count == save_count+1);
90     save_count = count;
91     A_void_1* ap = &a;
92     r1(ap);
93     INVOKE_NOEXCEPT(false, r1(ap));
94     assert(count == save_count+1);
95     save_count = count;
96     }
97     // const member function pointer
98     {
99     void (A_void_1::*fp)() const = &A_void_1::mem2;
100     std::reference_wrapper<void (A_void_1::*)() const> r1(fp);
101     A_void_1 a;
102     r1(a);
103     INVOKE_NOEXCEPT(false, r1(a));
104     assert(count == save_count+1);
105     save_count = count;
106     A_void_1* ap = &a;
107     r1(ap);
108     INVOKE_NOEXCEPT(false, r1(ap));
109     assert(count == save_count+1);
110     save_count = count;
111     }
112 }
113 
114 // 1 arg, return int
115 
f_int_1(int i)116 int f_int_1(int i)
117 {
118     return i + 1;
119 }
120 
121 struct A_int_1
122 {
A_int_1A_int_1123     A_int_1() : data_(5) {}
operator ()A_int_1124     int operator()(int i)
125     {
126         return i - 1;
127     }
128 
mem1A_int_1129     int mem1() {return 3;}
mem2A_int_1130     int mem2() const {return 4;}
131     int data_;
132 };
133 
134 void
test_int_1()135 test_int_1()
136 {
137     // function
138     {
139     std::reference_wrapper<int (int)> r1(f_int_1);
140     int i = 2;
141     assert(r1(i) == 3);
142     INVOKE_NOEXCEPT(false, r1(i));
143     }
144     // function pointer
145     {
146     int (*fp)(int) = f_int_1;
147     std::reference_wrapper<int (*)(int)> r1(fp);
148     int i = 3;
149     assert(r1(i) == 4);
150     INVOKE_NOEXCEPT(false, r1(i));
151     }
152     // functor
153     {
154     A_int_1 a0;
155     std::reference_wrapper<A_int_1> r1(a0);
156     int i = 4;
157     assert(r1(i) == 3);
158     INVOKE_NOEXCEPT(false, r1(i));
159     }
160     // member function pointer
161     {
162     int (A_int_1::*fp)() = &A_int_1::mem1;
163     std::reference_wrapper<int (A_int_1::*)()> r1(fp);
164     A_int_1 a;
165     assert(r1(a) == 3);
166     INVOKE_NOEXCEPT(false, r1(a));
167     A_int_1* ap = &a;
168     assert(r1(ap) == 3);
169     INVOKE_NOEXCEPT(false, r1(ap));
170     }
171     // const member function pointer
172     {
173     int (A_int_1::*fp)() const = &A_int_1::mem2;
174     std::reference_wrapper<int (A_int_1::*)() const> r1(fp);
175     A_int_1 a;
176     assert(r1(a) == 4);
177     INVOKE_NOEXCEPT(false, r1(a));
178     A_int_1* ap = &a;
179     assert(r1(ap) == 4);
180     INVOKE_NOEXCEPT(false, r1(ap));
181     }
182     // member data pointer
183     {
184     int A_int_1::*fp = &A_int_1::data_;
185     std::reference_wrapper<int A_int_1::*> r1(fp);
186     A_int_1 a;
187     assert(r1(a) == 5);
188     INVOKE_NOEXCEPT(true, r1(a));
189     r1(a) = 6;
190     assert(r1(a) == 6);
191     A_int_1* ap = &a;
192     assert(r1(ap) == 6);
193     r1(ap) = 7;
194     assert(r1(ap) == 7);
195     INVOKE_NOEXCEPT(true, r1(ap));
196     }
197 }
198 
199 // 2 arg, return void
200 
f_void_2(int i,int j)201 void f_void_2(int i, int j)
202 {
203     count += i+j;
204 }
205 
206 struct A_void_2
207 {
operator ()A_void_2208     void operator()(int i, int j)
209     {
210         count += i+j;
211     }
212 
mem1A_void_2213     void mem1(int i) {count += i;}
mem2A_void_2214     void mem2(int i) const {count += i;}
215 };
216 
217 void
test_void_2()218 test_void_2()
219 {
220     int save_count = count;
221     // function
222     {
223     std::reference_wrapper<void (int, int)> r1(f_void_2);
224     int i = 2;
225     int j = 3;
226     r1(i, j);
227     INVOKE_NOEXCEPT(false, r1(i, j));
228     assert(count == save_count+5);
229     save_count = count;
230     }
231     // function pointer
232     {
233     void (*fp)(int, int) = f_void_2;
234     std::reference_wrapper<void (*)(int, int)> r1(fp);
235     int i = 3;
236     int j = 4;
237     r1(i, j);
238     INVOKE_NOEXCEPT(false, r1(i, j));
239     assert(count == save_count+7);
240     save_count = count;
241     }
242     // functor
243     {
244     A_void_2 a0;
245     std::reference_wrapper<A_void_2> r1(a0);
246     int i = 4;
247     int j = 5;
248     r1(i, j);
249     INVOKE_NOEXCEPT(false, r1(i, j));
250     assert(count == save_count+9);
251     save_count = count;
252     }
253     // member function pointer
254     {
255     void (A_void_2::*fp)(int) = &A_void_2::mem1;
256     std::reference_wrapper<void (A_void_2::*)(int)> r1(fp);
257     A_void_2 a;
258     int i = 3;
259     r1(a, i);
260     assert(count == save_count+3);
261     save_count = count;
262     A_void_2* ap = &a;
263     r1(ap, i);
264     INVOKE_NOEXCEPT(false, r1(ap, i));
265     assert(count == save_count+3);
266     save_count = count;
267     }
268     // const member function pointer
269     {
270     void (A_void_2::*fp)(int) const = &A_void_2::mem2;
271     std::reference_wrapper<void (A_void_2::*)(int) const> r1(fp);
272     A_void_2 a;
273     int i = 4;
274     r1(a, i);
275     INVOKE_NOEXCEPT(false, r1(a, i));
276     assert(count == save_count+4);
277     save_count = count;
278     A_void_2* ap = &a;
279     r1(ap, i);
280     INVOKE_NOEXCEPT(false, r1(ap, i));
281     assert(count == save_count+4);
282     save_count = count;
283     }
284 }
285 
286 // 2 arg, return int
287 
f_int_2(int i,int j)288 int f_int_2(int i, int j)
289 {
290     return i+j;
291 }
292 
293 struct A_int_2
294 {
operator ()A_int_2295     int operator()(int i, int j)
296     {
297         return i+j;
298     }
299 
mem1A_int_2300     int mem1(int i) {return i+1;}
mem2A_int_2301     int mem2(int i) const {return i+2;}
302 };
303 
304 void
test_int_2()305 test_int_2()
306 {
307     // function
308     {
309     std::reference_wrapper<int (int, int)> r1(f_int_2);
310     int i = 2;
311     int j = 3;
312     assert(r1(i, j) == i+j);
313     INVOKE_NOEXCEPT(false, r1(i, j));
314     }
315     // function pointer
316     {
317     int (*fp)(int, int) = f_int_2;
318     std::reference_wrapper<int (*)(int, int)> r1(fp);
319     int i = 3;
320     int j = 4;
321     assert(r1(i, j) == i+j);
322     INVOKE_NOEXCEPT(false, r1(i, j));
323     }
324     // functor
325     {
326     A_int_2 a0;
327     std::reference_wrapper<A_int_2> r1(a0);
328     int i = 4;
329     int j = 5;
330     assert(r1(i, j) == i+j);
331     INVOKE_NOEXCEPT(false, r1(i, j));
332     }
333     // member function pointer
334     {
335     int(A_int_2::*fp)(int) = &A_int_2::mem1;
336     std::reference_wrapper<int (A_int_2::*)(int)> r1(fp);
337     A_int_2 a;
338     int i = 3;
339     assert(r1(a, i) == i+1);
340     INVOKE_NOEXCEPT(false, r1(a, i));
341     A_int_2* ap = &a;
342     assert(r1(ap, i) == i+1);
343     INVOKE_NOEXCEPT(false, r1(ap, i));
344     }
345     // const member function pointer
346     {
347     int (A_int_2::*fp)(int) const = &A_int_2::mem2;
348     std::reference_wrapper<int (A_int_2::*)(int) const> r1(fp);
349     A_int_2 a;
350     int i = 4;
351     assert(r1(a, i) == i+2);
352     INVOKE_NOEXCEPT(false, r1(a, i));
353     A_int_2* ap = &a;
354     assert(r1(ap, i) == i+2);
355     INVOKE_NOEXCEPT(false, r1(ap, i));
356     }
357 }
358 
359 #if TEST_STD_VER >= 11
360 
361 // 1 arg, return void, noexcept
362 
f_void_1_noexcept(int i)363 void f_void_1_noexcept(int i) noexcept
364 {
365     count += i;
366 }
367 
368 struct A_void_1_noexcept
369 {
operator ()A_void_1_noexcept370     void operator()(int i) noexcept
371     {
372         count += i;
373     }
374 
mem1A_void_1_noexcept375     void mem1() noexcept {++count;}
mem2A_void_1_noexcept376     void mem2() const noexcept {++count;}
377 };
378 
379 void
test_void_1_noexcept()380 test_void_1_noexcept()
381 {
382     int save_count = count;
383     // function
384     {
385     std::reference_wrapper<void (int) noexcept> r1(f_void_1_noexcept);
386     int i = 2;
387     r1(i);
388     INVOKE_NOEXCEPT(true, r1(i));
389     assert(count == save_count+2);
390     save_count = count;
391     }
392     // function pointer
393     {
394     void (*fp)(int) noexcept = f_void_1_noexcept;
395     std::reference_wrapper<void (*)(int) noexcept> r1(fp);
396     int i = 3;
397     r1(i);
398     INVOKE_NOEXCEPT(true, r1(i));
399     assert(count == save_count+3);
400     save_count = count;
401     }
402     // functor
403     {
404     A_void_1_noexcept a0;
405     std::reference_wrapper<A_void_1_noexcept> r1(a0);
406     int i = 4;
407     r1(i);
408     INVOKE_NOEXCEPT(true, r1(i));
409     assert(count == save_count+4);
410     save_count = count;
411     }
412     // member function pointer
413     {
414     void (A_void_1_noexcept::*fp)() noexcept = &A_void_1_noexcept::mem1;
415     std::reference_wrapper<void (A_void_1_noexcept::*)() noexcept> r1(fp);
416     A_void_1_noexcept a;
417     r1(a);
418     INVOKE_NOEXCEPT(true, r1(a));
419     assert(count == save_count+1);
420     save_count = count;
421     A_void_1_noexcept* ap = &a;
422     r1(ap);
423     INVOKE_NOEXCEPT(true, r1(ap));
424     assert(count == save_count+1);
425     save_count = count;
426     }
427     // const member function pointer
428     {
429     void (A_void_1_noexcept::*fp)() const noexcept = &A_void_1_noexcept::mem2;
430     std::reference_wrapper<void (A_void_1_noexcept::*)() const noexcept> r1(fp);
431     A_void_1_noexcept a;
432     r1(a);
433     INVOKE_NOEXCEPT(true, r1(a));
434     assert(count == save_count+1);
435     save_count = count;
436     A_void_1_noexcept* ap = &a;
437     r1(ap);
438     INVOKE_NOEXCEPT(true, r1(ap));
439     assert(count == save_count+1);
440     save_count = count;
441     }
442 }
443 
444 // 1 arg, return int, noexcept
445 
f_int_1_noexcept(int i)446 int f_int_1_noexcept(int i) noexcept
447 {
448     return i + 1;
449 }
450 
451 struct A_int_1_noexcept
452 {
A_int_1_noexceptA_int_1_noexcept453     A_int_1_noexcept() : data_(5) {}
operator ()A_int_1_noexcept454     int operator()(int i) noexcept
455     {
456         return i - 1;
457     }
458 
mem1A_int_1_noexcept459     int mem1() noexcept {return 3;}
mem2A_int_1_noexcept460     int mem2() const noexcept {return 4;}
461     int data_;
462 };
463 
464 void
test_int_1_noexcept()465 test_int_1_noexcept()
466 {
467     // function
468     {
469     std::reference_wrapper<int (int) noexcept> r1(f_int_1_noexcept);
470     int i = 2;
471     assert(r1(i) == 3);
472     INVOKE_NOEXCEPT(true, r1(i));
473     }
474     // function pointer
475     {
476     int (*fp)(int) noexcept = f_int_1_noexcept;
477     std::reference_wrapper<int (*)(int) noexcept> r1(fp);
478     int i = 3;
479     assert(r1(i) == 4);
480     INVOKE_NOEXCEPT(true, r1(i));
481     }
482     // functor
483     {
484     A_int_1_noexcept a0;
485     std::reference_wrapper<A_int_1_noexcept> r1(a0);
486     int i = 4;
487     assert(r1(i) == 3);
488     INVOKE_NOEXCEPT(true, r1(i));
489     }
490     // member function pointer
491     {
492     int (A_int_1_noexcept::*fp)() noexcept = &A_int_1_noexcept::mem1;
493     std::reference_wrapper<int (A_int_1_noexcept::*)() noexcept> r1(fp);
494     A_int_1_noexcept a;
495     assert(r1(a) == 3);
496     INVOKE_NOEXCEPT(true, r1(a));
497     A_int_1_noexcept* ap = &a;
498     assert(r1(ap) == 3);
499     INVOKE_NOEXCEPT(true, r1(ap));
500     }
501     // const member function pointer
502     {
503     int (A_int_1_noexcept::*fp)() const noexcept = &A_int_1_noexcept::mem2;
504     std::reference_wrapper<int (A_int_1_noexcept::*)() const noexcept> r1(fp);
505     A_int_1_noexcept a;
506     assert(r1(a) == 4);
507     INVOKE_NOEXCEPT(true, r1(a));
508     A_int_1_noexcept* ap = &a;
509     assert(r1(ap) == 4);
510     INVOKE_NOEXCEPT(true, r1(ap));
511     }
512     // member data pointer
513     {
514     int A_int_1_noexcept::*fp = &A_int_1_noexcept::data_;
515     std::reference_wrapper<int A_int_1_noexcept::*> r1(fp);
516     A_int_1_noexcept a;
517     assert(r1(a) == 5);
518     INVOKE_NOEXCEPT(true, r1(a));
519     r1(a) = 6;
520     assert(r1(a) == 6);
521     A_int_1_noexcept* ap = &a;
522     assert(r1(ap) == 6);
523     r1(ap) = 7;
524     assert(r1(ap) == 7);
525     INVOKE_NOEXCEPT(true, r1(ap));
526     }
527 }
528 
529 // 2 arg, return void, noexcept
530 
f_void_2_noexcept(int i,int j)531 void f_void_2_noexcept(int i, int j) noexcept
532 {
533     count += i+j;
534 }
535 
536 struct A_void_2_noexcept
537 {
operator ()A_void_2_noexcept538     void operator()(int i, int j) noexcept
539     {
540         count += i+j;
541     }
542 
mem1A_void_2_noexcept543     void mem1(int i) noexcept {count += i;}
mem2A_void_2_noexcept544     void mem2(int i) const noexcept {count += i;}
545 };
546 
547 void
test_void_2_noexcept()548 test_void_2_noexcept()
549 {
550     int save_count = count;
551     // function
552     {
553     std::reference_wrapper<void (int, int) noexcept> r1(f_void_2_noexcept);
554     int i = 2;
555     int j = 3;
556     r1(i, j);
557     INVOKE_NOEXCEPT(true, r1(i, j));
558     assert(count == save_count+5);
559     save_count = count;
560     }
561     // function pointer
562     {
563     void (*fp)(int, int) noexcept = f_void_2_noexcept;
564     std::reference_wrapper<void (*)(int, int) noexcept> r1(fp);
565     int i = 3;
566     int j = 4;
567     r1(i, j);
568     INVOKE_NOEXCEPT(true, r1(i, j));
569     assert(count == save_count+7);
570     save_count = count;
571     }
572     // functor
573     {
574     A_void_2_noexcept a0;
575     std::reference_wrapper<A_void_2_noexcept> r1(a0);
576     int i = 4;
577     int j = 5;
578     r1(i, j);
579     INVOKE_NOEXCEPT(true, r1(i, j));
580     assert(count == save_count+9);
581     save_count = count;
582     }
583     // member function pointer
584     {
585     void (A_void_2_noexcept::*fp)(int) noexcept = &A_void_2_noexcept::mem1;
586     std::reference_wrapper<void (A_void_2_noexcept::*)(int) noexcept> r1(fp);
587     A_void_2_noexcept a;
588     int i = 3;
589     r1(a, i);
590     assert(count == save_count+3);
591     save_count = count;
592     A_void_2_noexcept* ap = &a;
593     r1(ap, i);
594     INVOKE_NOEXCEPT(true, r1(ap, i));
595     assert(count == save_count+3);
596     save_count = count;
597     }
598     // const member function pointer
599     {
600     void (A_void_2_noexcept::*fp)(int) const noexcept = &A_void_2_noexcept::mem2;
601     std::reference_wrapper<void (A_void_2_noexcept::*)(int) const noexcept> r1(fp);
602     A_void_2_noexcept a;
603     int i = 4;
604     r1(a, i);
605     INVOKE_NOEXCEPT(true, r1(a, i));
606     assert(count == save_count+4);
607     save_count = count;
608     A_void_2_noexcept* ap = &a;
609     r1(ap, i);
610     INVOKE_NOEXCEPT(true, r1(ap, i));
611     assert(count == save_count+4);
612     save_count = count;
613     }
614 }
615 
616 // 2 arg, return int, noexcept
617 
f_int_2_noexcept(int i,int j)618 int f_int_2_noexcept(int i, int j) noexcept
619 {
620     return i+j;
621 }
622 
623 struct A_int_2_noexcept
624 {
operator ()A_int_2_noexcept625     int operator()(int i, int j) noexcept
626     {
627         return i+j;
628     }
629 
mem1A_int_2_noexcept630     int mem1(int i) noexcept {return i+1;}
mem2A_int_2_noexcept631     int mem2(int i) const noexcept {return i+2;}
632 };
633 
634 void
test_int_2_noexcept()635 test_int_2_noexcept()
636 {
637     // function
638     {
639     std::reference_wrapper<int (int, int) noexcept> r1(f_int_2_noexcept);
640     int i = 2;
641     int j = 3;
642     assert(r1(i, j) == i+j);
643     INVOKE_NOEXCEPT(true, r1(i, j));
644     }
645     // function pointer
646     {
647     int (*fp)(int, int) noexcept = f_int_2_noexcept;
648     std::reference_wrapper<int (*)(int, int) noexcept> r1(fp);
649     int i = 3;
650     int j = 4;
651     assert(r1(i, j) == i+j);
652     INVOKE_NOEXCEPT(true, r1(i, j));
653     }
654     // functor
655     {
656     A_int_2_noexcept a0;
657     std::reference_wrapper<A_int_2_noexcept> r1(a0);
658     int i = 4;
659     int j = 5;
660     assert(r1(i, j) == i+j);
661     INVOKE_NOEXCEPT(true, r1(i, j));
662     }
663     // member function pointer
664     {
665     int(A_int_2_noexcept::*fp)(int) noexcept = &A_int_2_noexcept::mem1;
666     std::reference_wrapper<int (A_int_2_noexcept::*)(int) noexcept> r1(fp);
667     A_int_2_noexcept a;
668     int i = 3;
669     assert(r1(a, i) == i+1);
670     INVOKE_NOEXCEPT(true, r1(a, i));
671     A_int_2_noexcept* ap = &a;
672     assert(r1(ap, i) == i+1);
673     INVOKE_NOEXCEPT(true, r1(ap, i));
674     }
675     // const member function pointer
676     {
677     int (A_int_2_noexcept::*fp)(int) const noexcept = &A_int_2_noexcept::mem2;
678     std::reference_wrapper<int (A_int_2_noexcept::*)(int) const noexcept> r1(fp);
679     A_int_2_noexcept a;
680     int i = 4;
681     assert(r1(a, i) == i+2);
682     INVOKE_NOEXCEPT(true, r1(a, i));
683     A_int_2_noexcept* ap = &a;
684     assert(r1(ap, i) == i+2);
685     INVOKE_NOEXCEPT(true, r1(ap, i));
686     }
687 }
688 
689 #endif // TEST_STD_VER >= 11
690 
main(int,char **)691 int main(int, char**)
692 {
693     test_void_1();
694     test_int_1();
695     test_void_2();
696     test_int_2();
697 #if TEST_STD_VER >= 11
698     test_void_1_noexcept();
699     test_int_1_noexcept();
700     test_void_2_noexcept();
701     test_int_2_noexcept();
702 #endif // TEST_STD_VER >= 11
703 
704   return 0;
705 }
706