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     std::bind(f_void_1, _1)(2);
53     assert(count == save_count + 2);
54     save_count = count;
55     }
56     {
57     std::bind(f_void_1, 2)();
58     assert(count == save_count + 2);
59     save_count = count;
60     }
61     // function pointer
62     {
63     void (*fp)(int) = f_void_1;
64     std::bind(fp, _1)(3);
65     assert(count == save_count+3);
66     save_count = count;
67     }
68     {
69     void (*fp)(int) = f_void_1;
70     std::bind(fp, 3)();
71     assert(count == save_count+3);
72     save_count = count;
73     }
74     // functor
75     {
76     A_void_1 a0;
77     std::bind(a0, _1)(4);
78     assert(count == save_count+4);
79     save_count = count;
80     }
81     {
82     A_void_1 a0;
83     std::bind(a0, 4)();
84     assert(count == save_count+4);
85     save_count = count;
86     }
87     // member function pointer
88     {
89     void (A_void_1::*fp)() = &A_void_1::mem1;
90     std::bind(fp, _1)(A_void_1());
91     assert(count == save_count+1);
92     save_count = count;
93     A_void_1 a;
94     std::bind(fp, _1)(&a);
95     assert(count == save_count+1);
96     save_count = count;
97     }
98     {
99     void (A_void_1::*fp)() = &A_void_1::mem1;
100     std::bind(fp, A_void_1())();
101     assert(count == save_count+1);
102     save_count = count;
103     A_void_1 a;
104     std::bind(fp, &a)();
105     assert(count == save_count+1);
106     save_count = count;
107     }
108     // const member function pointer
109     {
110     void (A_void_1::*fp)() const = &A_void_1::mem2;
111     std::bind(fp, _1)(A_void_1());
112     assert(count == save_count+2);
113     save_count = count;
114     A_void_1 a;
115     std::bind(fp, _1)(&a);
116     assert(count == save_count+2);
117     save_count = count;
118     }
119     {
120     void (A_void_1::*fp)() const = &A_void_1::mem2;
121     std::bind(fp, A_void_1())();
122     assert(count == save_count+2);
123     save_count = count;
124     A_void_1 a;
125     std::bind(fp, &a)();
126     assert(count == save_count+2);
127     save_count = count;
128     }
129 }
130 
131 // 1 arg, return int
132 
133 int f_int_1(int i)
134 {
135     return i + 1;
136 }
137 
138 struct A_int_1
139 {
140     A_int_1() : data_(5) {}
141     int operator()(int i)
142     {
143         return i - 1;
144     }
145 
146     int mem1() {return 3;}
147     int mem2() const {return 4;}
148     int data_;
149 };
150 
151 void
152 test_int_1()
153 {
154     using namespace std::placeholders;
155     // function
156     {
157     assert(std::bind(f_int_1, _1)(2) == 3);
158     assert(std::bind(f_int_1, 2)() == 3);
159     }
160     // function pointer
161     {
162     int (*fp)(int) = f_int_1;
163     assert(std::bind(fp, _1)(3) == 4);
164     assert(std::bind(fp, 3)() == 4);
165     }
166     // functor
167     {
168     assert(std::bind(A_int_1(), _1)(4) == 3);
169     assert(std::bind(A_int_1(), 4)() == 3);
170     }
171     // member function pointer
172     {
173     assert(std::bind(&A_int_1::mem1, _1)(A_int_1()) == 3);
174     assert(std::bind(&A_int_1::mem1, A_int_1())() == 3);
175     A_int_1 a;
176     assert(std::bind(&A_int_1::mem1, _1)(&a) == 3);
177     assert(std::bind(&A_int_1::mem1, &a)() == 3);
178     }
179     // const member function pointer
180     {
181     assert(std::bind(&A_int_1::mem2, _1)(A_int_1()) == 4);
182     assert(std::bind(&A_int_1::mem2, A_int_1())() == 4);
183     A_int_1 a;
184     assert(std::bind(&A_int_1::mem2, _1)(&a) == 4);
185     assert(std::bind(&A_int_1::mem2, &a)() == 4);
186     }
187     // member data pointer
188     {
189     assert(std::bind(&A_int_1::data_, _1)(A_int_1()) == 5);
190     assert(std::bind(&A_int_1::data_, A_int_1())() == 5);
191     A_int_1 a;
192     assert(std::bind(&A_int_1::data_, _1)(a) == 5);
193     std::bind(&A_int_1::data_, _1)(a) = 6;
194     assert(std::bind(&A_int_1::data_, _1)(a) == 6);
195     assert(std::bind(&A_int_1::data_, _1)(&a) == 6);
196     std::bind(&A_int_1::data_, _1)(&a) = 7;
197     assert(std::bind(&A_int_1::data_, _1)(&a) == 7);
198     }
199 }
200 
201 // 2 arg, return void
202 
203 void f_void_2(int i, int j)
204 {
205     count += i+j;
206 }
207 
208 struct A_void_2
209 {
210     void operator()(int i, int j)
211     {
212         count += i+j;
213     }
214 
215     void mem1(int i) {count += i;}
216     void mem2(int i) const {count += i;}
217 };
218 
219 void
220 test_void_2()
221 {
222     using namespace std::placeholders;
223     int save_count = count;
224     // function
225     {
226     std::bind(f_void_2, _1, _2)(2, 3);
227     assert(count == save_count+5);
228     save_count = count;
229     std::bind(f_void_2, 2, _1)(3);
230     assert(count == save_count+5);
231     save_count = count;
232     std::bind(f_void_2, 2, 3)();
233     assert(count == save_count+5);
234     save_count = count;
235     }
236     // member function pointer
237     {
238     std::bind(&A_void_2::mem1, _1, _2)(A_void_2(), 3);
239     assert(count == save_count+3);
240     save_count = count;
241     std::bind(&A_void_2::mem1, _2, _1)(3, A_void_2());
242     assert(count == save_count+3);
243     save_count = count;
244     }
245 }
246 
247 int f_nested(int i)
248 {
249     return i+1;
250 }
251 
252 int g_nested(int i)
253 {
254     return i*10;
255 }
256 
257 void test_nested()
258 {
259     using namespace std::placeholders;
260     assert(std::bind(f_nested, std::bind(g_nested, _1))(3) == 31);
261 }
262 
263 int main(int, char**)
264 {
265     test_void_1();
266     test_int_1();
267     test_void_2();
268     test_nested();
269 
270   return 0;
271 }
272