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 int i = 2;
535a83710eSEric Fiselier std::bind(f_void_1, _1)(i);
545a83710eSEric Fiselier assert(count == save_count + 2);
555a83710eSEric Fiselier save_count = count;
565a83710eSEric Fiselier }
575a83710eSEric Fiselier {
585a83710eSEric Fiselier int i = 2;
595a83710eSEric Fiselier std::bind(f_void_1, i)();
605a83710eSEric Fiselier assert(count == save_count + 2);
615a83710eSEric Fiselier save_count = count;
625a83710eSEric Fiselier }
635a83710eSEric Fiselier // function pointer
645a83710eSEric Fiselier {
655a83710eSEric Fiselier void (*fp)(int) = f_void_1;
665a83710eSEric Fiselier int i = 3;
675a83710eSEric Fiselier std::bind(fp, _1)(i);
685a83710eSEric Fiselier assert(count == save_count+3);
695a83710eSEric Fiselier save_count = count;
705a83710eSEric Fiselier }
715a83710eSEric Fiselier {
725a83710eSEric Fiselier void (*fp)(int) = f_void_1;
735a83710eSEric Fiselier int i = 3;
745a83710eSEric Fiselier std::bind(fp, i)();
755a83710eSEric Fiselier assert(count == save_count+3);
765a83710eSEric Fiselier save_count = count;
775a83710eSEric Fiselier }
785a83710eSEric Fiselier // functor
795a83710eSEric Fiselier {
805a83710eSEric Fiselier A_void_1 a0;
815a83710eSEric Fiselier int i = 4;
825a83710eSEric Fiselier std::bind(a0, _1)(i);
835a83710eSEric Fiselier assert(count == save_count+4);
845a83710eSEric Fiselier save_count = count;
855a83710eSEric Fiselier }
865a83710eSEric Fiselier {
875a83710eSEric Fiselier A_void_1 a0;
885a83710eSEric Fiselier int i = 4;
895a83710eSEric Fiselier std::bind(a0, i)();
905a83710eSEric Fiselier assert(count == save_count+4);
915a83710eSEric Fiselier save_count = count;
925a83710eSEric Fiselier }
935a83710eSEric Fiselier // member function pointer
945a83710eSEric Fiselier {
955a83710eSEric Fiselier void (A_void_1::*fp)() = &A_void_1::mem1;
965a83710eSEric Fiselier A_void_1 a;
975a83710eSEric Fiselier std::bind(fp, _1)(a);
985a83710eSEric Fiselier assert(count == save_count+1);
995a83710eSEric Fiselier save_count = count;
1005a83710eSEric Fiselier A_void_1* ap = &a;
1015a83710eSEric Fiselier std::bind(fp, _1)(ap);
1025a83710eSEric Fiselier assert(count == save_count+1);
1035a83710eSEric Fiselier save_count = count;
1045a83710eSEric Fiselier }
1055a83710eSEric Fiselier {
1065a83710eSEric Fiselier void (A_void_1::*fp)() = &A_void_1::mem1;
1075a83710eSEric Fiselier A_void_1 a;
1085a83710eSEric Fiselier std::bind(fp, a)();
1095a83710eSEric Fiselier assert(count == save_count+1);
1105a83710eSEric Fiselier save_count = count;
1115a83710eSEric Fiselier A_void_1* ap = &a;
1125a83710eSEric Fiselier std::bind(fp, ap)();
1135a83710eSEric Fiselier assert(count == save_count+1);
1145a83710eSEric Fiselier save_count = count;
1155a83710eSEric Fiselier }
1165a83710eSEric Fiselier // const member function pointer
1175a83710eSEric Fiselier {
1185a83710eSEric Fiselier void (A_void_1::*fp)() const = &A_void_1::mem2;
1195a83710eSEric Fiselier A_void_1 a;
1205a83710eSEric Fiselier std::bind(fp, _1)(a);
1215a83710eSEric Fiselier assert(count == save_count+2);
1225a83710eSEric Fiselier save_count = count;
1235a83710eSEric Fiselier A_void_1* ap = &a;
1245a83710eSEric Fiselier std::bind(fp, _1)(ap);
1255a83710eSEric Fiselier assert(count == save_count+2);
1265a83710eSEric Fiselier save_count = count;
1275a83710eSEric Fiselier }
1285a83710eSEric Fiselier {
1295a83710eSEric Fiselier void (A_void_1::*fp)() const = &A_void_1::mem2;
1305a83710eSEric Fiselier A_void_1 a;
1315a83710eSEric Fiselier std::bind(fp, a)();
1325a83710eSEric Fiselier assert(count == save_count+2);
1335a83710eSEric Fiselier save_count = count;
1345a83710eSEric Fiselier A_void_1* ap = &a;
1355a83710eSEric Fiselier std::bind(fp, ap)();
1365a83710eSEric Fiselier assert(count == save_count+2);
1375a83710eSEric Fiselier save_count = count;
1385a83710eSEric Fiselier }
1395a83710eSEric Fiselier }
1405a83710eSEric Fiselier
1415a83710eSEric Fiselier // 1 arg, return int
1425a83710eSEric Fiselier
f_int_1(int i)1435a83710eSEric Fiselier int f_int_1(int i)
1445a83710eSEric Fiselier {
1455a83710eSEric Fiselier return i + 1;
1465a83710eSEric Fiselier }
1475a83710eSEric Fiselier
1485a83710eSEric Fiselier struct A_int_1
1495a83710eSEric Fiselier {
A_int_1A_int_11505a83710eSEric Fiselier A_int_1() : data_(5) {}
operator ()A_int_11515a83710eSEric Fiselier int operator()(int i)
1525a83710eSEric Fiselier {
1535a83710eSEric Fiselier return i - 1;
1545a83710eSEric Fiselier }
1555a83710eSEric Fiselier
mem1A_int_11565a83710eSEric Fiselier int mem1() {return 3;}
mem2A_int_11575a83710eSEric Fiselier int mem2() const {return 4;}
1585a83710eSEric Fiselier int data_;
1595a83710eSEric Fiselier };
1605a83710eSEric Fiselier
1615a83710eSEric Fiselier void
test_int_1()1625a83710eSEric Fiselier test_int_1()
1635a83710eSEric Fiselier {
1645a83710eSEric Fiselier using namespace std::placeholders;
1655a83710eSEric Fiselier // function
1665a83710eSEric Fiselier {
1675a83710eSEric Fiselier int i = 2;
1685a83710eSEric Fiselier assert(std::bind(f_int_1, _1)(i) == 3);
1695a83710eSEric Fiselier assert(std::bind(f_int_1, i)() == 3);
1705a83710eSEric Fiselier }
1715a83710eSEric Fiselier // function pointer
1725a83710eSEric Fiselier {
1735a83710eSEric Fiselier int (*fp)(int) = f_int_1;
1745a83710eSEric Fiselier int i = 3;
1755a83710eSEric Fiselier assert(std::bind(fp, _1)(i) == 4);
1765a83710eSEric Fiselier assert(std::bind(fp, i)() == 4);
1775a83710eSEric Fiselier }
1785a83710eSEric Fiselier // functor
1795a83710eSEric Fiselier {
1805a83710eSEric Fiselier int i = 4;
1815a83710eSEric Fiselier assert(std::bind(A_int_1(), _1)(i) == 3);
1825a83710eSEric Fiselier assert(std::bind(A_int_1(), i)() == 3);
1835a83710eSEric Fiselier }
1845a83710eSEric Fiselier // member function pointer
1855a83710eSEric Fiselier {
1865a83710eSEric Fiselier A_int_1 a;
1875a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, _1)(a) == 3);
1885a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, a)() == 3);
1895a83710eSEric Fiselier A_int_1* ap = &a;
1905a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, _1)(ap) == 3);
1915a83710eSEric Fiselier assert(std::bind(&A_int_1::mem1, ap)() == 3);
1925a83710eSEric Fiselier }
1935a83710eSEric Fiselier // const member function pointer
1945a83710eSEric Fiselier {
1955a83710eSEric Fiselier A_int_1 a;
1965a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4);
1975a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, A_int_1())() == 4);
1985a83710eSEric Fiselier A_int_1* ap = &a;
1995a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, _1)(ap) == 4);
2005a83710eSEric Fiselier assert(std::bind(&A_int_1::mem2, ap)() == 4);
2015a83710eSEric Fiselier }
2025a83710eSEric Fiselier // member data pointer
2035a83710eSEric Fiselier {
2045a83710eSEric Fiselier A_int_1 a;
2055a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(a) == 5);
2065a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, a)() == 5);
2075a83710eSEric Fiselier A_int_1* ap = &a;
2085a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(a) == 5);
2095a83710eSEric Fiselier std::bind(&A_int_1::data_, _1)(a) = 6;
2105a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(a) == 6);
2115a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(ap) == 6);
2125a83710eSEric Fiselier std::bind(&A_int_1::data_, _1)(ap) = 7;
2135a83710eSEric Fiselier assert(std::bind(&A_int_1::data_, _1)(ap) == 7);
2145a83710eSEric Fiselier }
2155a83710eSEric Fiselier }
2165a83710eSEric Fiselier
2175a83710eSEric Fiselier // 2 arg, return void
2185a83710eSEric Fiselier
f_void_2(int i,int j)2195a83710eSEric Fiselier void f_void_2(int i, int j)
2205a83710eSEric Fiselier {
2215a83710eSEric Fiselier count += i+j;
2225a83710eSEric Fiselier }
2235a83710eSEric Fiselier
2245a83710eSEric Fiselier struct A_void_2
2255a83710eSEric Fiselier {
operator ()A_void_22265a83710eSEric Fiselier void operator()(int i, int j)
2275a83710eSEric Fiselier {
2285a83710eSEric Fiselier count += i+j;
2295a83710eSEric Fiselier }
2305a83710eSEric Fiselier
mem1A_void_22315a83710eSEric Fiselier void mem1(int i) {count += i;}
mem2A_void_22325a83710eSEric Fiselier void mem2(int i) const {count += i;}
2335a83710eSEric Fiselier };
2345a83710eSEric Fiselier
2355a83710eSEric Fiselier void
test_void_2()2365a83710eSEric Fiselier test_void_2()
2375a83710eSEric Fiselier {
2385a83710eSEric Fiselier using namespace std::placeholders;
2395a83710eSEric Fiselier int save_count = count;
2405a83710eSEric Fiselier // function
2415a83710eSEric Fiselier {
2425a83710eSEric Fiselier int i = 2;
2435a83710eSEric Fiselier int j = 3;
2445a83710eSEric Fiselier std::bind(f_void_2, _1, _2)(i, j);
2455a83710eSEric Fiselier assert(count == save_count+5);
2465a83710eSEric Fiselier save_count = count;
2475a83710eSEric Fiselier std::bind(f_void_2, i, _1)(j);
2485a83710eSEric Fiselier assert(count == save_count+5);
2495a83710eSEric Fiselier save_count = count;
2505a83710eSEric Fiselier std::bind(f_void_2, i, j)();
2515a83710eSEric Fiselier assert(count == save_count+5);
2525a83710eSEric Fiselier save_count = count;
2535a83710eSEric Fiselier }
2545a83710eSEric Fiselier // member function pointer
2555a83710eSEric Fiselier {
2565a83710eSEric Fiselier int j = 3;
2575a83710eSEric Fiselier std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), j);
2585a83710eSEric Fiselier assert(count == save_count+3);
2595a83710eSEric Fiselier save_count = count;
2605a83710eSEric Fiselier std::bind(&A_void_2::mem1, _2, _1)(j, A_void_2());
2615a83710eSEric Fiselier assert(count == save_count+3);
2625a83710eSEric Fiselier save_count = count;
2635a83710eSEric Fiselier }
2645a83710eSEric Fiselier }
2655a83710eSEric Fiselier
2665a83710eSEric Fiselier struct TFENode
2675a83710eSEric Fiselier {
fooTFENode2685a83710eSEric Fiselier bool foo(unsigned long long) const
2695a83710eSEric Fiselier {
2705a83710eSEric Fiselier return true;
2715a83710eSEric Fiselier }
2725a83710eSEric Fiselier };
2735a83710eSEric Fiselier
2745a83710eSEric Fiselier void
test3()2755a83710eSEric Fiselier test3()
2765a83710eSEric Fiselier {
2775a83710eSEric Fiselier using namespace std;
2785a83710eSEric Fiselier using namespace std::placeholders;
2795a83710eSEric Fiselier const auto f = bind(&TFENode::foo, _1, 0UL);
2805a83710eSEric Fiselier const TFENode n = TFENode{};
2815a83710eSEric Fiselier bool b = f(n);
282c281a7a1SEric Fiselier assert(b);
2835a83710eSEric Fiselier }
2845a83710eSEric Fiselier
main(int,char **)2852df59c50SJF Bastien int main(int, char**)
2865a83710eSEric Fiselier {
2875a83710eSEric Fiselier test_void_1();
2885a83710eSEric Fiselier test_int_1();
2895a83710eSEric Fiselier test_void_2();
29058ff77c2SEric Fiselier test3();
2912df59c50SJF Bastien
2922df59c50SJF Bastien return 0;
2935a83710eSEric Fiselier }
294