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