706 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// <functional>10 11// reference_wrapper12 13// template <class... ArgTypes>14// constexpr typename result_of<T&(ArgTypes&&...)>::type // constexpr since C++2015// operator() (ArgTypes&&...) const16// noexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // noexcept since C++1717 18#include <functional>19#include <cassert>20 21#include "test_macros.h"22 23#if TEST_STD_VER > 1424# define INVOKE_NOEXCEPT(expected, ...) static_assert(noexcept(__VA_ARGS__) == expected)25#else26# define INVOKE_NOEXCEPT(expected, ...)27#endif28 29int count = 0;30 31// 1 arg, return void32 33void f_void_1(int i)34{35 count += i;36}37 38struct A_void_139{40 void operator()(int i)41 {42 count += i;43 }44 45 void mem1() {++count;}46 void mem2() const {++count;}47};48 49void50test_void_1()51{52 int save_count = count;53 // function54 {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 pointer63 {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 // functor73 {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 pointer83 {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 pointer98 {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 int115 116int f_int_1(int i)117{118 return i + 1;119}120 121struct A_int_1122{123 A_int_1() : data_(5) {}124 int operator()(int i)125 {126 return i - 1;127 }128 129 int mem1() {return 3;}130 int mem2() const {return 4;}131 int data_;132};133 134void135test_int_1()136{137 // function138 {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 pointer145 {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 // functor153 {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 pointer161 {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 pointer172 {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 pointer183 {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 void200 201void f_void_2(int i, int j)202{203 count += i+j;204}205 206struct A_void_2207{208 void operator()(int i, int j)209 {210 count += i+j;211 }212 213 void mem1(int i) {count += i;}214 void mem2(int i) const {count += i;}215};216 217void218test_void_2()219{220 int save_count = count;221 // function222 {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 pointer232 {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 // functor243 {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 pointer254 {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 pointer269 {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 int287 288int f_int_2(int i, int j)289{290 return i+j;291}292 293struct A_int_2294{295 int operator()(int i, int j)296 {297 return i+j;298 }299 300 int mem1(int i) {return i+1;}301 int mem2(int i) const {return i+2;}302};303 304void305test_int_2()306{307 // function308 {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 pointer316 {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 // functor325 {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 pointer334 {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 pointer346 {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 >= 11360 361// 1 arg, return void, noexcept362 363void f_void_1_noexcept(int i) noexcept364{365 count += i;366}367 368struct A_void_1_noexcept369{370 void operator()(int i) noexcept371 {372 count += i;373 }374 375 void mem1() noexcept {++count;}376 void mem2() const noexcept {++count;}377};378 379void380test_void_1_noexcept()381{382 int save_count = count;383 // function384 {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 pointer393 {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 // functor403 {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 pointer413 {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 pointer428 {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, noexcept445 446int f_int_1_noexcept(int i) noexcept447{448 return i + 1;449}450 451struct A_int_1_noexcept452{453 A_int_1_noexcept() : data_(5) {}454 int operator()(int i) noexcept455 {456 return i - 1;457 }458 459 int mem1() noexcept {return 3;}460 int mem2() const noexcept {return 4;}461 int data_;462};463 464void465test_int_1_noexcept()466{467 // function468 {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 pointer475 {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 // functor483 {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 pointer491 {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 pointer502 {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 pointer513 {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, noexcept530 531void f_void_2_noexcept(int i, int j) noexcept532{533 count += i+j;534}535 536struct A_void_2_noexcept537{538 void operator()(int i, int j) noexcept539 {540 count += i+j;541 }542 543 void mem1(int i) noexcept {count += i;}544 void mem2(int i) const noexcept {count += i;}545};546 547void548test_void_2_noexcept()549{550 int save_count = count;551 // function552 {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 pointer562 {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 // functor573 {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 pointer584 {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 pointer599 {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, noexcept617 618int f_int_2_noexcept(int i, int j) noexcept619{620 return i+j;621}622 623struct A_int_2_noexcept624{625 int operator()(int i, int j) noexcept626 {627 return i+j;628 }629 630 int mem1(int i) noexcept {return i+1;}631 int mem2(int i) const noexcept {return i+2;}632};633 634void635test_int_2_noexcept()636{637 // function638 {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 pointer646 {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 // functor655 {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 pointer664 {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 pointer676 {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 >= 11690 691int 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 >= 11698 test_void_1_noexcept();699 test_int_1_noexcept();700 test_void_2_noexcept();701 test_int_2_noexcept();702#endif // TEST_STD_VER >= 11703 704 return 0;705}706