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