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++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
f_void_1(int i)29 void f_void_1(int i)
30 {
31 count += i;
32 }
33
34 struct A_void_1
35 {
operator ()A_void_136 void operator()(int i)
37 {
38 count += i;
39 }
40
mem1A_void_141 void mem1() {++count;}
mem2A_void_142 void mem2() const {count += 2;}
43 };
44
45 void
test_void_1()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
f_int_1(int i)143 int f_int_1(int i)
144 {
145 return i + 1;
146 }
147
148 struct A_int_1
149 {
A_int_1A_int_1150 A_int_1() : data_(5) {}
operator ()A_int_1151 int operator()(int i)
152 {
153 return i - 1;
154 }
155
mem1A_int_1156 int mem1() {return 3;}
mem2A_int_1157 int mem2() const {return 4;}
158 int data_;
159 };
160
161 void
test_int_1()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
f_void_2(int i,int j)219 void f_void_2(int i, int j)
220 {
221 count += i+j;
222 }
223
224 struct A_void_2
225 {
operator ()A_void_2226 void operator()(int i, int j)
227 {
228 count += i+j;
229 }
230
mem1A_void_2231 void mem1(int i) {count += i;}
mem2A_void_2232 void mem2(int i) const {count += i;}
233 };
234
235 void
test_void_2()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 {
fooTFENode268 bool foo(unsigned long long) const
269 {
270 return true;
271 }
272 };
273
274 void
test3()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
main(int,char **)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