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