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
9*31cbe0f2SLouis Dionne // UNSUPPORTED: c++03
10e5407178SEric Fiselier
115a83710eSEric Fiselier // <functional>
125a83710eSEric Fiselier
135a83710eSEric Fiselier // template<CopyConstructible Fn, CopyConstructible... Types>
145a83710eSEric Fiselier // unspecified bind(Fn, Types...);
155a83710eSEric Fiselier // template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>
165a83710eSEric Fiselier // unspecified bind(Fn, Types...);
175a83710eSEric Fiselier
185a83710eSEric Fiselier #include <stdio.h>
195a83710eSEric Fiselier
205a83710eSEric Fiselier #include <functional>
215a83710eSEric Fiselier #include <cassert>
225a83710eSEric Fiselier
237fc6a556SMarshall Clow #include "test_macros.h"
247fc6a556SMarshall Clow
255a83710eSEric Fiselier int count = 0;
265a83710eSEric Fiselier
275a83710eSEric Fiselier // 1 arg, return void
285a83710eSEric Fiselier
f_void_1(int i)295a83710eSEric Fiselier void f_void_1(int i)
305a83710eSEric Fiselier {
315a83710eSEric Fiselier count += i;
325a83710eSEric Fiselier }
335a83710eSEric Fiselier
345a83710eSEric Fiselier struct A_void_1
355a83710eSEric Fiselier {
operator ()A_void_1365a83710eSEric Fiselier void operator()(int i)
375a83710eSEric Fiselier {
385a83710eSEric Fiselier count += i;
395a83710eSEric Fiselier }
405a83710eSEric Fiselier
mem1A_void_1415a83710eSEric Fiselier void mem1() {++count;}
mem2A_void_1425a83710eSEric Fiselier void mem2() const {count += 2;}
435a83710eSEric Fiselier };
445a83710eSEric Fiselier
455a83710eSEric Fiselier void
test_void_1()465a83710eSEric Fiselier test_void_1()
475a83710eSEric Fiselier {
485a83710eSEric Fiselier using namespace std::placeholders;
495a83710eSEric Fiselier int save_count = count;
505a83710eSEric Fiselier // function
515a83710eSEric Fiselier {
525a83710eSEric Fiselier std::bind(f_void_1, _1)(2);
535a83710eSEric Fiselier assert(count == save_count + 2);
545a83710eSEric Fiselier save_count = count;
555a83710eSEric Fiselier }
565a83710eSEric Fiselier {
575a83710eSEric Fiselier std::bind(f_void_1, 2)();
585a83710eSEric Fiselier assert(count == save_count + 2);
595a83710eSEric Fiselier save_count = count;
605a83710eSEric Fiselier }
615a83710eSEric Fiselier // function pointer
625a83710eSEric Fiselier {
635a83710eSEric Fiselier void (*fp)(int) = f_void_1;
645a83710eSEric Fiselier std::bind(fp, _1)(3);
655a83710eSEric Fiselier assert(count == save_count+3);
665a83710eSEric Fiselier save_count = count;
675a83710eSEric Fiselier }
685a83710eSEric Fiselier {
695a83710eSEric Fiselier void (*fp)(int) = f_void_1;
705a83710eSEric Fiselier std::bind(fp, 3)();
715a83710eSEric Fiselier assert(count == save_count+3);
725a83710eSEric Fiselier save_count = count;
735a83710eSEric Fiselier }
745a83710eSEric Fiselier // functor
755a83710eSEric Fiselier {
765a83710eSEric Fiselier A_void_1 a0;
775a83710eSEric Fiselier std::bind(a0, _1)(4);
785a83710eSEric Fiselier assert(count == save_count+4);
795a83710eSEric Fiselier save_count = count;
805a83710eSEric Fiselier }
815a83710eSEric Fiselier {
825a83710eSEric Fiselier A_void_1 a0;
835a83710eSEric Fiselier std::bind(a0, 4)();
845a83710eSEric Fiselier assert(count == save_count+4);
855a83710eSEric Fiselier save_count = count;
865a83710eSEric Fiselier }
875a83710eSEric Fiselier // member function pointer
885a83710eSEric Fiselier {
895a83710eSEric Fiselier void (A_void_1::*fp)() = &A_void_1::mem1;
905a83710eSEric Fiselier std::bind(fp, _1)(A_void_1());
915a83710eSEric Fiselier assert(count == save_count+1);
925a83710eSEric Fiselier save_count = count;
935a83710eSEric Fiselier A_void_1 a;
945a83710eSEric Fiselier std::bind(fp, _1)(&a);
955a83710eSEric Fiselier assert(count == save_count+1);
965a83710eSEric Fiselier save_count = count;
975a83710eSEric Fiselier }
985a83710eSEric Fiselier {
995a83710eSEric Fiselier void (A_void_1::*fp)() = &A_void_1::mem1;
1005a83710eSEric Fiselier std::bind(fp, A_void_1())();
1015a83710eSEric Fiselier assert(count == save_count+1);
1025a83710eSEric Fiselier save_count = count;
1035a83710eSEric Fiselier A_void_1 a;
1045a83710eSEric Fiselier std::bind(fp, &a)();
1055a83710eSEric Fiselier assert(count == save_count+1);
1065a83710eSEric Fiselier save_count = count;
1075a83710eSEric Fiselier }
1085a83710eSEric Fiselier // const member function pointer
1095a83710eSEric Fiselier {
1105a83710eSEric Fiselier void (A_void_1::*fp)() const = &A_void_1::mem2;
1115a83710eSEric Fiselier std::bind(fp, _1)(A_void_1());
1125a83710eSEric Fiselier assert(count == save_count+2);
1135a83710eSEric Fiselier save_count = count;
1145a83710eSEric Fiselier A_void_1 a;
1155a83710eSEric Fiselier std::bind(fp, _1)(&a);
1165a83710eSEric Fiselier assert(count == save_count+2);
1175a83710eSEric Fiselier save_count = count;
1185a83710eSEric Fiselier }
1195a83710eSEric Fiselier {
1205a83710eSEric Fiselier void (A_void_1::*fp)() const = &A_void_1::mem2;
1215a83710eSEric Fiselier std::bind(fp, A_void_1())();
1225a83710eSEric Fiselier assert(count == save_count+2);
1235a83710eSEric Fiselier save_count = count;
1245a83710eSEric Fiselier A_void_1 a;
1255a83710eSEric Fiselier std::bind(fp, &a)();
1265a83710eSEric Fiselier assert(count == save_count+2);
1275a83710eSEric Fiselier save_count = count;
1285a83710eSEric Fiselier }
1295a83710eSEric Fiselier }
1305a83710eSEric Fiselier
1315a83710eSEric Fiselier // 1 arg, return int
1325a83710eSEric Fiselier
f_int_1(int i)1335a83710eSEric Fiselier int f_int_1(int i)
1345a83710eSEric Fiselier {
1355a83710eSEric Fiselier return i + 1;
1365a83710eSEric Fiselier }
1375a83710eSEric Fiselier
1385a83710eSEric Fiselier struct A_int_1
1395a83710eSEric Fiselier {
A_int_1A_int_11405a83710eSEric Fiselier A_int_1() : data_(5) {}
operator ()A_int_11415a83710eSEric Fiselier int operator()(int i)
1425a83710eSEric Fiselier {
1435a83710eSEric Fiselier return i - 1;
1445a83710eSEric Fiselier }
1455a83710eSEric Fiselier
mem1A_int_11465a83710eSEric Fiselier int mem1() {return 3;}
mem2A_int_11475a83710eSEric Fiselier int mem2() const {return 4;}
1485a83710eSEric Fiselier int data_;
1495a83710eSEric Fiselier };
1505a83710eSEric Fiselier
1515a83710eSEric Fiselier void
test_int_1()1525a83710eSEric Fiselier test_int_1()
1535a83710eSEric Fiselier {
1545a83710eSEric Fiselier using namespace std::placeholders;
1555a83710eSEric Fiselier // function
1565a83710eSEric Fiselier {
1575a83710eSEric Fiselier assert(std::bind(f_int_1, _1)(2) == 3);
1585a83710eSEric Fiselier assert(std::bind(f_int_1, 2)() == 3);
1595a83710eSEric Fiselier }
1605a83710eSEric Fiselier // function pointer
1615a83710eSEric Fiselier {
1625a83710eSEric Fiselier int (*fp)(int) = f_int_1;
1635a83710eSEric Fiselier assert(std::bind(fp, _1)(3) == 4);
1645a83710eSEric Fiselier assert(std::bind(fp, 3)() == 4);
1655a83710eSEric Fiselier }
1665a83710eSEric Fiselier // functor
1675a83710eSEric Fiselier {
1685a83710eSEric Fiselier assert(std::bind(A_int_1(), _1)(4) == 3);
1695a83710eSEric Fiselier assert(std::bind(A_int_1(), 4)() == 3);
1705a83710eSEric Fiselier }
1715a83710eSEric Fiselier // member function pointer
1725a83710eSEric Fiselier {
1735a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, _1)(A_int_1()) == 3);
1745a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, A_int_1())() == 3);
1755a83710eSEric Fiselier A_int_1 a;
1765a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, _1)(&a) == 3);
1775a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, &a)() == 3);
1785a83710eSEric Fiselier }
1795a83710eSEric Fiselier // const member function pointer
1805a83710eSEric Fiselier {
1815a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4);
1825a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, A_int_1())() == 4);
1835a83710eSEric Fiselier A_int_1 a;
1845a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, _1)(&a) == 4);
1855a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, &a)() == 4);
1865a83710eSEric Fiselier }
1875a83710eSEric Fiselier // member data pointer
1885a83710eSEric Fiselier {
1895a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(A_int_1()) == 5);
1905a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, A_int_1())() == 5);
1915a83710eSEric Fiselier A_int_1 a;
1925a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(a) == 5);
1935a83710eSEric Fiselier std::bind(&A_int_1::data_, _1)(a) = 6;
1945a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(a) == 6);
1955a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(&a) == 6);
1965a83710eSEric Fiselier std::bind(&A_int_1::data_, _1)(&a) = 7;
1975a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(&a) == 7);
1985a83710eSEric Fiselier }
1995a83710eSEric Fiselier }
2005a83710eSEric Fiselier
2015a83710eSEric Fiselier // 2 arg, return void
2025a83710eSEric Fiselier
f_void_2(int i,int j)2035a83710eSEric Fiselier void f_void_2(int i, int j)
2045a83710eSEric Fiselier {
2055a83710eSEric Fiselier count += i+j;
2065a83710eSEric Fiselier }
2075a83710eSEric Fiselier
2085a83710eSEric Fiselier struct A_void_2
2095a83710eSEric Fiselier {
operator ()A_void_22105a83710eSEric Fiselier void operator()(int i, int j)
2115a83710eSEric Fiselier {
2125a83710eSEric Fiselier count += i+j;
2135a83710eSEric Fiselier }
2145a83710eSEric Fiselier
mem1A_void_22155a83710eSEric Fiselier void mem1(int i) {count += i;}
mem2A_void_22165a83710eSEric Fiselier void mem2(int i) const {count += i;}
2175a83710eSEric Fiselier };
2185a83710eSEric Fiselier
2195a83710eSEric Fiselier void
test_void_2()2205a83710eSEric Fiselier test_void_2()
2215a83710eSEric Fiselier {
2225a83710eSEric Fiselier using namespace std::placeholders;
2235a83710eSEric Fiselier int save_count = count;
2245a83710eSEric Fiselier // function
2255a83710eSEric Fiselier {
2265a83710eSEric Fiselier std::bind(f_void_2, _1, _2)(2, 3);
2275a83710eSEric Fiselier assert(count == save_count+5);
2285a83710eSEric Fiselier save_count = count;
2295a83710eSEric Fiselier std::bind(f_void_2, 2, _1)(3);
2305a83710eSEric Fiselier assert(count == save_count+5);
2315a83710eSEric Fiselier save_count = count;
2325a83710eSEric Fiselier std::bind(f_void_2, 2, 3)();
2335a83710eSEric Fiselier assert(count == save_count+5);
2345a83710eSEric Fiselier save_count = count;
2355a83710eSEric Fiselier }
2365a83710eSEric Fiselier // member function pointer
2375a83710eSEric Fiselier {
2385a83710eSEric Fiselier std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), 3);
2395a83710eSEric Fiselier assert(count == save_count+3);
2405a83710eSEric Fiselier save_count = count;
2415a83710eSEric Fiselier std::bind(&A_void_2::mem1, _2, _1)(3, A_void_2());
2425a83710eSEric Fiselier assert(count == save_count+3);
2435a83710eSEric Fiselier save_count = count;
2445a83710eSEric Fiselier }
2455a83710eSEric Fiselier }
2465a83710eSEric Fiselier
f_nested(int i)2475a83710eSEric Fiselier int f_nested(int i)
2485a83710eSEric Fiselier {
2495a83710eSEric Fiselier return i+1;
2505a83710eSEric Fiselier }
2515a83710eSEric Fiselier
g_nested(int i)2525a83710eSEric Fiselier int g_nested(int i)
2535a83710eSEric Fiselier {
2545a83710eSEric Fiselier return i*10;
2555a83710eSEric Fiselier }
2565a83710eSEric Fiselier
test_nested()2575a83710eSEric Fiselier void test_nested()
2585a83710eSEric Fiselier {
2595a83710eSEric Fiselier using namespace std::placeholders;
2605a83710eSEric Fiselier assert(std::bind(f_nested, std::bind(g_nested, _1))(3) == 31);
2615a83710eSEric Fiselier }
2625a83710eSEric Fiselier
main(int,char **)2632df59c50SJF Bastien int main(int, char**)
2645a83710eSEric Fiselier {
2655a83710eSEric Fiselier test_void_1();
2665a83710eSEric Fiselier test_int_1();
2675a83710eSEric Fiselier test_void_2();
2685a83710eSEric Fiselier test_nested();
2692df59c50SJF Bastien
2702df59c50SJF Bastien return 0;
2715a83710eSEric Fiselier }
272