1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // UNSUPPORTED: c++98, c++03
11 
12 // <functional>
13 
14 // template<CopyConstructible Fn, CopyConstructible... Types>
15 //   unspecified bind(Fn, Types...);
16 // template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>
17 //   unspecified bind(Fn, Types...);
18 
19 #include <stdio.h>
20 
21 #include <functional>
22 #include <cassert>
23 
24 int count = 0;
25 
26 // 1 arg, return void
27 
f_void_1(int i)28 void f_void_1(int i)
29 {
30     count += i;
31 }
32 
33 struct A_void_1
34 {
operator ()A_void_135     void operator()(int i)
36     {
37         count += i;
38     }
39 
mem1A_void_140     void mem1() {++count;}
mem2A_void_141     void mem2() const {count += 2;}
42 };
43 
44 void
test_void_1()45 test_void_1()
46 {
47     using namespace std::placeholders;
48     int save_count = count;
49     // function
50     {
51     int i = 2;
52     std::bind(f_void_1, _1)(i);
53     assert(count == save_count + 2);
54     save_count = count;
55     }
56     {
57     int i = 2;
58     std::bind(f_void_1, i)();
59     assert(count == save_count + 2);
60     save_count = count;
61     }
62     // function pointer
63     {
64     void (*fp)(int) = f_void_1;
65     int i = 3;
66     std::bind(fp, _1)(i);
67     assert(count == save_count+3);
68     save_count = count;
69     }
70     {
71     void (*fp)(int) = f_void_1;
72     int i = 3;
73     std::bind(fp, i)();
74     assert(count == save_count+3);
75     save_count = count;
76     }
77     // functor
78     {
79     A_void_1 a0;
80     int i = 4;
81     std::bind(a0, _1)(i);
82     assert(count == save_count+4);
83     save_count = count;
84     }
85     {
86     A_void_1 a0;
87     int i = 4;
88     std::bind(a0, i)();
89     assert(count == save_count+4);
90     save_count = count;
91     }
92     // member function pointer
93     {
94     void (A_void_1::*fp)() = &A_void_1::mem1;
95     A_void_1 a;
96     std::bind(fp, _1)(a);
97     assert(count == save_count+1);
98     save_count = count;
99     A_void_1* ap = &a;
100     std::bind(fp, _1)(ap);
101     assert(count == save_count+1);
102     save_count = count;
103     }
104     {
105     void (A_void_1::*fp)() = &A_void_1::mem1;
106     A_void_1 a;
107     std::bind(fp, a)();
108     assert(count == save_count+1);
109     save_count = count;
110     A_void_1* ap = &a;
111     std::bind(fp, ap)();
112     assert(count == save_count+1);
113     save_count = count;
114     }
115     // const member function pointer
116     {
117     void (A_void_1::*fp)() const = &A_void_1::mem2;
118     A_void_1 a;
119     std::bind(fp, _1)(a);
120     assert(count == save_count+2);
121     save_count = count;
122     A_void_1* ap = &a;
123     std::bind(fp, _1)(ap);
124     assert(count == save_count+2);
125     save_count = count;
126     }
127     {
128     void (A_void_1::*fp)() const = &A_void_1::mem2;
129     A_void_1 a;
130     std::bind(fp, a)();
131     assert(count == save_count+2);
132     save_count = count;
133     A_void_1* ap = &a;
134     std::bind(fp, ap)();
135     assert(count == save_count+2);
136     save_count = count;
137     }
138 }
139 
140 // 1 arg, return int
141 
f_int_1(int i)142 int f_int_1(int i)
143 {
144     return i + 1;
145 }
146 
147 struct A_int_1
148 {
A_int_1A_int_1149     A_int_1() : data_(5) {}
operator ()A_int_1150     int operator()(int i)
151     {
152         return i - 1;
153     }
154 
mem1A_int_1155     int mem1() {return 3;}
mem2A_int_1156     int mem2() const {return 4;}
157     int data_;
158 };
159 
160 void
test_int_1()161 test_int_1()
162 {
163     using namespace std::placeholders;
164     // function
165     {
166     int i = 2;
167     assert(std::bind(f_int_1, _1)(i) == 3);
168     assert(std::bind(f_int_1, i)() == 3);
169     }
170     // function pointer
171     {
172     int (*fp)(int) = f_int_1;
173     int i = 3;
174     assert(std::bind(fp, _1)(i) == 4);
175     assert(std::bind(fp, i)() == 4);
176     }
177     // functor
178     {
179     int i = 4;
180     assert(std::bind(A_int_1(), _1)(i) == 3);
181     assert(std::bind(A_int_1(), i)() == 3);
182     }
183     // member function pointer
184     {
185     A_int_1 a;
186     assert(std::bind(&A_int_1::mem1, _1)(a) == 3);
187     assert(std::bind(&A_int_1::mem1, a)() == 3);
188     A_int_1* ap = &a;
189     assert(std::bind(&A_int_1::mem1, _1)(ap) == 3);
190     assert(std::bind(&A_int_1::mem1, ap)() == 3);
191     }
192     // const member function pointer
193     {
194     A_int_1 a;
195     assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4);
196     assert(std::bind(&A_int_1::mem2, A_int_1())() == 4);
197     A_int_1* ap = &a;
198     assert(std::bind(&A_int_1::mem2, _1)(ap) == 4);
199     assert(std::bind(&A_int_1::mem2, ap)() == 4);
200     }
201     // member data pointer
202     {
203     A_int_1 a;
204     assert(std::bind(&A_int_1::data_, _1)(a) == 5);
205     assert(std::bind(&A_int_1::data_, a)() == 5);
206     A_int_1* ap = &a;
207     assert(std::bind(&A_int_1::data_, _1)(a) == 5);
208     std::bind(&A_int_1::data_, _1)(a) = 6;
209     assert(std::bind(&A_int_1::data_, _1)(a) == 6);
210     assert(std::bind(&A_int_1::data_, _1)(ap) == 6);
211     std::bind(&A_int_1::data_, _1)(ap) = 7;
212     assert(std::bind(&A_int_1::data_, _1)(ap) == 7);
213     }
214 }
215 
216 // 2 arg, return void
217 
f_void_2(int i,int j)218 void f_void_2(int i, int j)
219 {
220     count += i+j;
221 }
222 
223 struct A_void_2
224 {
operator ()A_void_2225     void operator()(int i, int j)
226     {
227         count += i+j;
228     }
229 
mem1A_void_2230     void mem1(int i) {count += i;}
mem2A_void_2231     void mem2(int i) const {count += i;}
232 };
233 
234 void
test_void_2()235 test_void_2()
236 {
237     using namespace std::placeholders;
238     int save_count = count;
239     // function
240     {
241     int i = 2;
242     int j = 3;
243     std::bind(f_void_2, _1, _2)(i, j);
244     assert(count == save_count+5);
245     save_count = count;
246     std::bind(f_void_2, i, _1)(j);
247     assert(count == save_count+5);
248     save_count = count;
249     std::bind(f_void_2, i, j)();
250     assert(count == save_count+5);
251     save_count = count;
252     }
253     // member function pointer
254     {
255     int j = 3;
256     std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), j);
257     assert(count == save_count+3);
258     save_count = count;
259     std::bind(&A_void_2::mem1, _2, _1)(j, A_void_2());
260     assert(count == save_count+3);
261     save_count = count;
262     }
263 }
264 
265 struct TFENode
266 {
fooTFENode267     bool foo(unsigned long long) const
268     {
269         return true;
270     }
271 };
272 
273 void
test3()274 test3()
275 {
276     using namespace std;
277     using namespace std::placeholders;
278     const auto f = bind(&TFENode::foo, _1, 0UL);
279     const TFENode n = TFENode{};
280     bool b = f(n);
281     assert(b);
282 }
283 
main()284 int main()
285 {
286     test_void_1();
287     test_int_1();
288     test_void_2();
289 }
290