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