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