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