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 test3();
290 }
291