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