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
f_void_1(int i)26 void f_void_1(int i)
27 {
28 count += i;
29 }
30
31 struct A_void_1
32 {
operator ()A_void_133 void operator()(int i)
34 {
35 count += i;
36 }
37
mem1A_void_138 void mem1() {++count;}
mem2A_void_139 void mem2() const {count += 2;}
40 };
41
42 void
test_void_1()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
f_int_1(int i)140 int f_int_1(int i)
141 {
142 return i + 1;
143 }
144
145 struct A_int_1
146 {
A_int_1A_int_1147 A_int_1() : data_(5) {}
operator ()A_int_1148 int operator()(int i)
149 {
150 return i - 1;
151 }
152
mem1A_int_1153 int mem1() {return 3;}
mem2A_int_1154 int mem2() const {return 4;}
155 int data_;
156 };
157
158 void
test_int_1()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
f_void_2(int i,int j)216 void f_void_2(int i, int j)
217 {
218 count += i+j;
219 }
220
221 struct A_void_2
222 {
operator ()A_void_2223 void operator()(int i, int j)
224 {
225 count += i+j;
226 }
227
mem1A_void_2228 void mem1(int i) {count += i;}
mem2A_void_2229 void mem2(int i) const {count += i;}
230 };
231
232 void
test_void_2()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 {
fooTFENode265 bool foo(unsigned long long) const
266 {
267 return true;
268 }
269 };
270
271 void
test3()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
main()281 int main()
282 {
283 test_void_1();
284 test_int_1();
285 test_void_2();
286 }
287