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