15a83710eSEric Fiselier //===----------------------------------------------------------------------===// 25a83710eSEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65a83710eSEric Fiselier // 75a83710eSEric Fiselier //===----------------------------------------------------------------------===// 85a83710eSEric Fiselier 95a83710eSEric Fiselier // <functional> 105a83710eSEric Fiselier 115a83710eSEric Fiselier // reference_wrapper 125a83710eSEric Fiselier 135a83710eSEric Fiselier // template <class... ArgTypes> 145a83710eSEric Fiselier // requires Callable<T, ArgTypes&&...> 155a83710eSEric Fiselier // Callable<T, ArgTypes&&...>::result_type 165a83710eSEric Fiselier // operator()(ArgTypes&&... args) const; 175a83710eSEric Fiselier 185a83710eSEric Fiselier #include <functional> 195a83710eSEric Fiselier #include <cassert> 205a83710eSEric Fiselier 215a83710eSEric Fiselier int count = 0; 225a83710eSEric Fiselier 235a83710eSEric Fiselier // 1 arg, return void 245a83710eSEric Fiselier 255a83710eSEric Fiselier void f_void_1(int i) 265a83710eSEric Fiselier { 275a83710eSEric Fiselier count += i; 285a83710eSEric Fiselier } 295a83710eSEric Fiselier 305a83710eSEric Fiselier struct A_void_1 315a83710eSEric Fiselier { 325a83710eSEric Fiselier void operator()(int i) 335a83710eSEric Fiselier { 345a83710eSEric Fiselier count += i; 355a83710eSEric Fiselier } 365a83710eSEric Fiselier 375a83710eSEric Fiselier void mem1() {++count;} 385a83710eSEric Fiselier void mem2() const {++count;} 395a83710eSEric Fiselier }; 405a83710eSEric Fiselier 415a83710eSEric Fiselier void 425a83710eSEric Fiselier test_void_1() 435a83710eSEric Fiselier { 445a83710eSEric Fiselier int save_count = count; 455a83710eSEric Fiselier // function 465a83710eSEric Fiselier { 475a83710eSEric Fiselier std::reference_wrapper<void (int)> r1(f_void_1); 485a83710eSEric Fiselier int i = 2; 495a83710eSEric Fiselier r1(i); 505a83710eSEric Fiselier assert(count == save_count+2); 515a83710eSEric Fiselier save_count = count; 525a83710eSEric Fiselier } 535a83710eSEric Fiselier // function pointer 545a83710eSEric Fiselier { 555a83710eSEric Fiselier void (*fp)(int) = f_void_1; 565a83710eSEric Fiselier std::reference_wrapper<void (*)(int)> r1(fp); 575a83710eSEric Fiselier int i = 3; 585a83710eSEric Fiselier r1(i); 595a83710eSEric Fiselier assert(count == save_count+3); 605a83710eSEric Fiselier save_count = count; 615a83710eSEric Fiselier } 625a83710eSEric Fiselier // functor 635a83710eSEric Fiselier { 645a83710eSEric Fiselier A_void_1 a0; 655a83710eSEric Fiselier std::reference_wrapper<A_void_1> r1(a0); 665a83710eSEric Fiselier int i = 4; 675a83710eSEric Fiselier r1(i); 685a83710eSEric Fiselier assert(count == save_count+4); 695a83710eSEric Fiselier save_count = count; 705a83710eSEric Fiselier } 715a83710eSEric Fiselier // member function pointer 725a83710eSEric Fiselier { 735a83710eSEric Fiselier void (A_void_1::*fp)() = &A_void_1::mem1; 745a83710eSEric Fiselier std::reference_wrapper<void (A_void_1::*)()> r1(fp); 755a83710eSEric Fiselier A_void_1 a; 765a83710eSEric Fiselier r1(a); 775a83710eSEric Fiselier assert(count == save_count+1); 785a83710eSEric Fiselier save_count = count; 795a83710eSEric Fiselier A_void_1* ap = &a; 805a83710eSEric Fiselier r1(ap); 815a83710eSEric Fiselier assert(count == save_count+1); 825a83710eSEric Fiselier save_count = count; 835a83710eSEric Fiselier } 845a83710eSEric Fiselier // const member function pointer 855a83710eSEric Fiselier { 865a83710eSEric Fiselier void (A_void_1::*fp)() const = &A_void_1::mem2; 875a83710eSEric Fiselier std::reference_wrapper<void (A_void_1::*)() const> r1(fp); 885a83710eSEric Fiselier A_void_1 a; 895a83710eSEric Fiselier r1(a); 905a83710eSEric Fiselier assert(count == save_count+1); 915a83710eSEric Fiselier save_count = count; 925a83710eSEric Fiselier A_void_1* ap = &a; 935a83710eSEric Fiselier r1(ap); 945a83710eSEric Fiselier assert(count == save_count+1); 955a83710eSEric Fiselier save_count = count; 965a83710eSEric Fiselier } 975a83710eSEric Fiselier } 985a83710eSEric Fiselier 995a83710eSEric Fiselier // 1 arg, return int 1005a83710eSEric Fiselier 1015a83710eSEric Fiselier int f_int_1(int i) 1025a83710eSEric Fiselier { 1035a83710eSEric Fiselier return i + 1; 1045a83710eSEric Fiselier } 1055a83710eSEric Fiselier 1065a83710eSEric Fiselier struct A_int_1 1075a83710eSEric Fiselier { 1085a83710eSEric Fiselier A_int_1() : data_(5) {} 1095a83710eSEric Fiselier int operator()(int i) 1105a83710eSEric Fiselier { 1115a83710eSEric Fiselier return i - 1; 1125a83710eSEric Fiselier } 1135a83710eSEric Fiselier 1145a83710eSEric Fiselier int mem1() {return 3;} 1155a83710eSEric Fiselier int mem2() const {return 4;} 1165a83710eSEric Fiselier int data_; 1175a83710eSEric Fiselier }; 1185a83710eSEric Fiselier 1195a83710eSEric Fiselier void 1205a83710eSEric Fiselier test_int_1() 1215a83710eSEric Fiselier { 1225a83710eSEric Fiselier // function 1235a83710eSEric Fiselier { 1245a83710eSEric Fiselier std::reference_wrapper<int (int)> r1(f_int_1); 1255a83710eSEric Fiselier int i = 2; 1265a83710eSEric Fiselier assert(r1(i) == 3); 1275a83710eSEric Fiselier } 1285a83710eSEric Fiselier // function pointer 1295a83710eSEric Fiselier { 1305a83710eSEric Fiselier int (*fp)(int) = f_int_1; 1315a83710eSEric Fiselier std::reference_wrapper<int (*)(int)> r1(fp); 1325a83710eSEric Fiselier int i = 3; 1335a83710eSEric Fiselier assert(r1(i) == 4); 1345a83710eSEric Fiselier } 1355a83710eSEric Fiselier // functor 1365a83710eSEric Fiselier { 1375a83710eSEric Fiselier A_int_1 a0; 1385a83710eSEric Fiselier std::reference_wrapper<A_int_1> r1(a0); 1395a83710eSEric Fiselier int i = 4; 1405a83710eSEric Fiselier assert(r1(i) == 3); 1415a83710eSEric Fiselier } 1425a83710eSEric Fiselier // member function pointer 1435a83710eSEric Fiselier { 1445a83710eSEric Fiselier int (A_int_1::*fp)() = &A_int_1::mem1; 1455a83710eSEric Fiselier std::reference_wrapper<int (A_int_1::*)()> r1(fp); 1465a83710eSEric Fiselier A_int_1 a; 1475a83710eSEric Fiselier assert(r1(a) == 3); 1485a83710eSEric Fiselier A_int_1* ap = &a; 1495a83710eSEric Fiselier assert(r1(ap) == 3); 1505a83710eSEric Fiselier } 1515a83710eSEric Fiselier // const member function pointer 1525a83710eSEric Fiselier { 1535a83710eSEric Fiselier int (A_int_1::*fp)() const = &A_int_1::mem2; 1545a83710eSEric Fiselier std::reference_wrapper<int (A_int_1::*)() const> r1(fp); 1555a83710eSEric Fiselier A_int_1 a; 1565a83710eSEric Fiselier assert(r1(a) == 4); 1575a83710eSEric Fiselier A_int_1* ap = &a; 1585a83710eSEric Fiselier assert(r1(ap) == 4); 1595a83710eSEric Fiselier } 1605a83710eSEric Fiselier // member data pointer 1615a83710eSEric Fiselier { 1625a83710eSEric Fiselier int A_int_1::*fp = &A_int_1::data_; 1635a83710eSEric Fiselier std::reference_wrapper<int A_int_1::*> r1(fp); 1645a83710eSEric Fiselier A_int_1 a; 1655a83710eSEric Fiselier assert(r1(a) == 5); 1665a83710eSEric Fiselier r1(a) = 6; 1675a83710eSEric Fiselier assert(r1(a) == 6); 1685a83710eSEric Fiselier A_int_1* ap = &a; 1695a83710eSEric Fiselier assert(r1(ap) == 6); 1705a83710eSEric Fiselier r1(ap) = 7; 1715a83710eSEric Fiselier assert(r1(ap) == 7); 1725a83710eSEric Fiselier } 1735a83710eSEric Fiselier } 1745a83710eSEric Fiselier 1755a83710eSEric Fiselier // 2 arg, return void 1765a83710eSEric Fiselier 1775a83710eSEric Fiselier void f_void_2(int i, int j) 1785a83710eSEric Fiselier { 1795a83710eSEric Fiselier count += i+j; 1805a83710eSEric Fiselier } 1815a83710eSEric Fiselier 1825a83710eSEric Fiselier struct A_void_2 1835a83710eSEric Fiselier { 1845a83710eSEric Fiselier void operator()(int i, int j) 1855a83710eSEric Fiselier { 1865a83710eSEric Fiselier count += i+j; 1875a83710eSEric Fiselier } 1885a83710eSEric Fiselier 1895a83710eSEric Fiselier void mem1(int i) {count += i;} 1905a83710eSEric Fiselier void mem2(int i) const {count += i;} 1915a83710eSEric Fiselier }; 1925a83710eSEric Fiselier 1935a83710eSEric Fiselier void 1945a83710eSEric Fiselier test_void_2() 1955a83710eSEric Fiselier { 1965a83710eSEric Fiselier int save_count = count; 1975a83710eSEric Fiselier // function 1985a83710eSEric Fiselier { 1995a83710eSEric Fiselier std::reference_wrapper<void (int, int)> r1(f_void_2); 2005a83710eSEric Fiselier int i = 2; 2015a83710eSEric Fiselier int j = 3; 2025a83710eSEric Fiselier r1(i, j); 2035a83710eSEric Fiselier assert(count == save_count+5); 2045a83710eSEric Fiselier save_count = count; 2055a83710eSEric Fiselier } 2065a83710eSEric Fiselier // function pointer 2075a83710eSEric Fiselier { 2085a83710eSEric Fiselier void (*fp)(int, int) = f_void_2; 2095a83710eSEric Fiselier std::reference_wrapper<void (*)(int, int)> r1(fp); 2105a83710eSEric Fiselier int i = 3; 2115a83710eSEric Fiselier int j = 4; 2125a83710eSEric Fiselier r1(i, j); 2135a83710eSEric Fiselier assert(count == save_count+7); 2145a83710eSEric Fiselier save_count = count; 2155a83710eSEric Fiselier } 2165a83710eSEric Fiselier // functor 2175a83710eSEric Fiselier { 2185a83710eSEric Fiselier A_void_2 a0; 2195a83710eSEric Fiselier std::reference_wrapper<A_void_2> r1(a0); 2205a83710eSEric Fiselier int i = 4; 2215a83710eSEric Fiselier int j = 5; 2225a83710eSEric Fiselier r1(i, j); 2235a83710eSEric Fiselier assert(count == save_count+9); 2245a83710eSEric Fiselier save_count = count; 2255a83710eSEric Fiselier } 2265a83710eSEric Fiselier // member function pointer 2275a83710eSEric Fiselier { 2285a83710eSEric Fiselier void (A_void_2::*fp)(int) = &A_void_2::mem1; 2295a83710eSEric Fiselier std::reference_wrapper<void (A_void_2::*)(int)> r1(fp); 2305a83710eSEric Fiselier A_void_2 a; 2315a83710eSEric Fiselier int i = 3; 2325a83710eSEric Fiselier r1(a, i); 2335a83710eSEric Fiselier assert(count == save_count+3); 2345a83710eSEric Fiselier save_count = count; 2355a83710eSEric Fiselier A_void_2* ap = &a; 2365a83710eSEric Fiselier r1(ap, i); 2375a83710eSEric Fiselier assert(count == save_count+3); 2385a83710eSEric Fiselier save_count = count; 2395a83710eSEric Fiselier } 2405a83710eSEric Fiselier // const member function pointer 2415a83710eSEric Fiselier { 2425a83710eSEric Fiselier void (A_void_2::*fp)(int) const = &A_void_2::mem2; 2435a83710eSEric Fiselier std::reference_wrapper<void (A_void_2::*)(int) const> r1(fp); 2445a83710eSEric Fiselier A_void_2 a; 2455a83710eSEric Fiselier int i = 4; 2465a83710eSEric Fiselier r1(a, i); 2475a83710eSEric Fiselier assert(count == save_count+4); 2485a83710eSEric Fiselier save_count = count; 2495a83710eSEric Fiselier A_void_2* ap = &a; 2505a83710eSEric Fiselier r1(ap, i); 2515a83710eSEric Fiselier assert(count == save_count+4); 2525a83710eSEric Fiselier save_count = count; 2535a83710eSEric Fiselier } 2545a83710eSEric Fiselier } 2555a83710eSEric Fiselier 2565a83710eSEric Fiselier // 2 arg, return int 2575a83710eSEric Fiselier 2585a83710eSEric Fiselier int f_int_2(int i, int j) 2595a83710eSEric Fiselier { 2605a83710eSEric Fiselier return i+j; 2615a83710eSEric Fiselier } 2625a83710eSEric Fiselier 2635a83710eSEric Fiselier struct A_int_2 2645a83710eSEric Fiselier { 2655a83710eSEric Fiselier int operator()(int i, int j) 2665a83710eSEric Fiselier { 2675a83710eSEric Fiselier return i+j; 2685a83710eSEric Fiselier } 2695a83710eSEric Fiselier 2705a83710eSEric Fiselier int mem1(int i) {return i+1;} 2715a83710eSEric Fiselier int mem2(int i) const {return i+2;} 2725a83710eSEric Fiselier }; 2735a83710eSEric Fiselier 2745a83710eSEric Fiselier void 2755a83710eSEric Fiselier testint_2() 2765a83710eSEric Fiselier { 2775a83710eSEric Fiselier // function 2785a83710eSEric Fiselier { 2795a83710eSEric Fiselier std::reference_wrapper<int (int, int)> r1(f_int_2); 2805a83710eSEric Fiselier int i = 2; 2815a83710eSEric Fiselier int j = 3; 2825a83710eSEric Fiselier assert(r1(i, j) == i+j); 2835a83710eSEric Fiselier } 2845a83710eSEric Fiselier // function pointer 2855a83710eSEric Fiselier { 2865a83710eSEric Fiselier int (*fp)(int, int) = f_int_2; 2875a83710eSEric Fiselier std::reference_wrapper<int (*)(int, int)> r1(fp); 2885a83710eSEric Fiselier int i = 3; 2895a83710eSEric Fiselier int j = 4; 2905a83710eSEric Fiselier assert(r1(i, j) == i+j); 2915a83710eSEric Fiselier } 2925a83710eSEric Fiselier // functor 2935a83710eSEric Fiselier { 2945a83710eSEric Fiselier A_int_2 a0; 2955a83710eSEric Fiselier std::reference_wrapper<A_int_2> r1(a0); 2965a83710eSEric Fiselier int i = 4; 2975a83710eSEric Fiselier int j = 5; 2985a83710eSEric Fiselier assert(r1(i, j) == i+j); 2995a83710eSEric Fiselier } 3005a83710eSEric Fiselier // member function pointer 3015a83710eSEric Fiselier { 3025a83710eSEric Fiselier int(A_int_2::*fp)(int) = &A_int_2::mem1; 3035a83710eSEric Fiselier std::reference_wrapper<int (A_int_2::*)(int)> r1(fp); 3045a83710eSEric Fiselier A_int_2 a; 3055a83710eSEric Fiselier int i = 3; 3065a83710eSEric Fiselier assert(r1(a, i) == i+1); 3075a83710eSEric Fiselier A_int_2* ap = &a; 3085a83710eSEric Fiselier assert(r1(ap, i) == i+1); 3095a83710eSEric Fiselier } 3105a83710eSEric Fiselier // const member function pointer 3115a83710eSEric Fiselier { 3125a83710eSEric Fiselier int (A_int_2::*fp)(int) const = &A_int_2::mem2; 3135a83710eSEric Fiselier std::reference_wrapper<int (A_int_2::*)(int) const> r1(fp); 3145a83710eSEric Fiselier A_int_2 a; 3155a83710eSEric Fiselier int i = 4; 3165a83710eSEric Fiselier assert(r1(a, i) == i+2); 3175a83710eSEric Fiselier A_int_2* ap = &a; 3185a83710eSEric Fiselier assert(r1(ap, i) == i+2); 3195a83710eSEric Fiselier } 3205a83710eSEric Fiselier } 3215a83710eSEric Fiselier 322*2df59c50SJF Bastien int main(int, char**) 3235a83710eSEric Fiselier { 3245a83710eSEric Fiselier test_void_1(); 3255a83710eSEric Fiselier test_int_1(); 3265a83710eSEric Fiselier test_void_2(); 3275a83710eSEric Fiselier testint_2(); 328*2df59c50SJF Bastien 329*2df59c50SJF Bastien return 0; 3305a83710eSEric Fiselier } 331