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++03
10
11// <functional>
12
13// class function<R(ArgTypes...)>
14
15// R operator()(ArgTypes... args) const
16
17// This test runs in C++03, but we have deprecated using std::function in C++03.
18// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
19
20// Address Sanitizer doesn't instrument weak symbols on Linux. When a key
21// function is defined for bad_function_call's vtable, its typeinfo and vtable
22// will be defined as strong symbols in the library and weak symbols in other
23// translation units. Only the strong symbol will be instrumented, increasing
24// its size (due to the redzone) and leading to a serious ODR violation
25// resulting in a crash.
26// Some relevant bugs:
27// https://github.com/google/sanitizers/issues/1017
28// https://github.com/google/sanitizers/issues/619
29// https://github.com/google/sanitizers/issues/398
30// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016
31// UNSUPPORTED: asan
32
33#include <functional>
34#include <cassert>
35
36#include "test_macros.h"
37
38
39int count = 0;
40
41
42// 0 args, return int
43
44int f_int_0()
45{
46 return 3;
47}
48
49struct A_int_0
50{
51 int operator()() {return 4;}
52};
53
54void test_int_0()
55{
56 // function
57 {
58 std::function<int ()> r1(f_int_0);
59 assert(r1() == 3);
60 }
61 // function pointer
62 {
63 int (*fp)() = f_int_0;
64 std::function<int ()> r1(fp);
65 assert(r1() == 3);
66 }
67 // functor
68 {
69 A_int_0 a0;
70 std::function<int ()> r1(a0);
71 assert(r1() == 4);
72 }
73}
74
75
76// 0 args, return void
77
78void f_void_0()
79{
80 ++count;
81}
82
83struct A_void_0
84{
85 void operator()() {++count;}
86};
87
88void
89test_void_0()
90{
91 int save_count = count;
92 // function
93 {
94 std::function<void ()> r1(f_void_0);
95 r1();
96 assert(count == save_count+1);
97 save_count = count;
98 }
99 // function pointer
100 {
101 void (*fp)() = f_void_0;
102 std::function<void ()> r1(fp);
103 r1();
104 assert(count == save_count+1);
105 save_count = count;
106 }
107 // functor
108 {
109 A_void_0 a0;
110 std::function<void ()> r1(a0);
111 r1();
112 assert(count == save_count+1);
113 save_count = count;
114 }
115}
116
117// 1 arg, return void
118
119void f_void_1(int i)
120{
121 count += i;
122}
123
124struct A_void_1
125{
126 void operator()(int i)
127 {
128 count += i;
129 }
130
131 void mem1() {++count;}
132 void mem2() const {++count;}
133};
134
135void
136test_void_1()
137{
138 int save_count = count;
139 // function
140 {
141 std::function<void (int)> r1(f_void_1);
142 int i = 2;
143 r1(i);
144 assert(count == save_count+2);
145 save_count = count;
146 }
147 // function pointer
148 {
149 void (*fp)(int) = f_void_1;
150 std::function<void (int)> r1(fp);
151 int i = 3;
152 r1(i);
153 assert(count == save_count+3);
154 save_count = count;
155 }
156 // functor
157 {
158 A_void_1 a0;
159 std::function<void (int)> r1(a0);
160 int i = 4;
161 r1(i);
162 assert(count == save_count+4);
163 save_count = count;
164 }
165 // member function pointer
166 {
167 void (A_void_1::*fp)() = &A_void_1::mem1;
168 std::function<void (A_void_1)> r1(fp);
169 A_void_1 a;
170 r1(a);
171 assert(count == save_count+1);
172 save_count = count;
173 A_void_1* ap = &a;
174 std::function<void (A_void_1*)> r2 = fp;
175 r2(ap);
176 assert(count == save_count+1);
177 save_count = count;
178 }
179 // const member function pointer
180 {
181 void (A_void_1::*fp)() const = &A_void_1::mem2;
182 std::function<void (A_void_1)> r1(fp);
183 A_void_1 a;
184 r1(a);
185 assert(count == save_count+1);
186 save_count = count;
187 std::function<void (A_void_1*)> r2(fp);
188 A_void_1* ap = &a;
189 r2(ap);
190 assert(count == save_count+1);
191 save_count = count;
192 }
193}
194
195// 1 arg, return int
196
197int f_int_1(int i)
198{
199 return i + 1;
200}
201
202struct A_int_1
203{
204 A_int_1() : data_(5) {}
205 int operator()(int i)
206 {
207 return i - 1;
208 }
209
210 int mem1() {return 3;}
211 int mem2() const {return 4;}
212 int data_;
213};
214
215void
216test_int_1()
217{
218 // function
219 {
220 std::function<int (int)> r1(f_int_1);
221 int i = 2;
222 assert(r1(i) == 3);
223 }
224 // function pointer
225 {
226 int (*fp)(int) = f_int_1;
227 std::function<int (int)> r1(fp);
228 int i = 3;
229 assert(r1(i) == 4);
230 }
231 // functor
232 {
233 A_int_1 a0;
234 std::function<int (int)> r1(a0);
235 int i = 4;
236 assert(r1(i) == 3);
237 }
238 // member function pointer
239 {
240 int (A_int_1::*fp)() = &A_int_1::mem1;
241 std::function<int (A_int_1)> r1(fp);
242 A_int_1 a;
243 assert(r1(a) == 3);
244 std::function<int (A_int_1*)> r2(fp);
245 A_int_1* ap = &a;
246 assert(r2(ap) == 3);
247 }
248 // const member function pointer
249 {
250 int (A_int_1::*fp)() const = &A_int_1::mem2;
251 std::function<int (A_int_1)> r1(fp);
252 A_int_1 a;
253 assert(r1(a) == 4);
254 std::function<int (A_int_1*)> r2(fp);
255 A_int_1* ap = &a;
256 assert(r2(ap) == 4);
257 }
258 // member data pointer
259 {
260 int A_int_1::*fp = &A_int_1::data_;
261 std::function<int& (A_int_1&)> r1(fp);
262 A_int_1 a;
263 assert(r1(a) == 5);
264 r1(a) = 6;
265 assert(r1(a) == 6);
266 std::function<int& (A_int_1*)> r2(fp);
267 A_int_1* ap = &a;
268 assert(r2(ap) == 6);
269 r2(ap) = 7;
270 assert(r2(ap) == 7);
271 }
272}
273
274// 2 arg, return void
275
276void f_void_2(int i, int j)
277{
278 count += i+j;
279}
280
281struct A_void_2
282{
283 void operator()(int i, int j)
284 {
285 count += i+j;
286 }
287
288 void mem1(int i) {count += i;}
289 void mem2(int i) const {count += i;}
290};
291
292void
293test_void_2()
294{
295 int save_count = count;
296 // function
297 {
298 std::function<void (int, int)> r1(f_void_2);
299 int i = 2;
300 int j = 3;
301 r1(i, j);
302 assert(count == save_count+5);
303 save_count = count;
304 }
305 // function pointer
306 {
307 void (*fp)(int, int) = f_void_2;
308 std::function<void (int, int)> r1(fp);
309 int i = 3;
310 int j = 4;
311 r1(i, j);
312 assert(count == save_count+7);
313 save_count = count;
314 }
315 // functor
316 {
317 A_void_2 a0;
318 std::function<void (int, int)> r1(a0);
319 int i = 4;
320 int j = 5;
321 r1(i, j);
322 assert(count == save_count+9);
323 save_count = count;
324 }
325 // member function pointer
326 {
327 void (A_void_2::*fp)(int) = &A_void_2::mem1;
328 std::function<void (A_void_2, int)> r1(fp);
329 A_void_2 a;
330 int i = 3;
331 r1(a, i);
332 assert(count == save_count+3);
333 save_count = count;
334 std::function<void (A_void_2*, int)> r2(fp);
335 A_void_2* ap = &a;
336 r2(ap, i);
337 assert(count == save_count+3);
338 save_count = count;
339 }
340 // const member function pointer
341 {
342 void (A_void_2::*fp)(int) const = &A_void_2::mem2;
343 std::function<void (A_void_2, int)> r1(fp);
344 A_void_2 a;
345 int i = 4;
346 r1(a, i);
347 assert(count == save_count+4);
348 save_count = count;
349 std::function<void (A_void_2*, int)> r2(fp);
350 A_void_2* ap = &a;
351 r2(ap, i);
352 assert(count == save_count+4);
353 save_count = count;
354 }
355}
356
357// 2 arg, return int
358
359int f_int_2(int i, int j)
360{
361 return i+j;
362}
363
364struct A_int_2
365{
366 int operator()(int i, int j)
367 {
368 return i+j;
369 }
370
371 int mem1(int i) {return i+1;}
372 int mem2(int i) const {return i+2;}
373};
374
375void test_int_2()
376{
377 // function
378 {
379 std::function<int (int, int)> r1(f_int_2);
380 int i = 2;
381 int j = 3;
382 assert(r1(i, j) == i+j);
383 }
384 // function pointer
385 {
386 int (*fp)(int, int) = f_int_2;
387 std::function<int (int, int)> r1(fp);
388 int i = 3;
389 int j = 4;
390 assert(r1(i, j) == i+j);
391 }
392 // functor
393 {
394 A_int_2 a0;
395 std::function<int (int, int)> r1(a0);
396 int i = 4;
397 int j = 5;
398 assert(r1(i, j) == i+j);
399 }
400 // member function pointer
401 {
402 int(A_int_2::*fp)(int) = &A_int_2::mem1;
403 std::function<int (A_int_2, int)> r1(fp);
404 A_int_2 a;
405 int i = 3;
406 assert(r1(a, i) == i+1);
407 std::function<int (A_int_2*, int)> r2(fp);
408 A_int_2* ap = &a;
409 assert(r2(ap, i) == i+1);
410 }
411 // const member function pointer
412 {
413 int (A_int_2::*fp)(int) const = &A_int_2::mem2;
414 std::function<int (A_int_2, int)> r1(fp);
415 A_int_2 a;
416 int i = 4;
417 assert(r1(a, i) == i+2);
418 std::function<int (A_int_2*, int)> r2(fp);
419 A_int_2* ap = &a;
420 assert(r2(ap, i) == i+2);
421 }
422}
423
424int main(int, char**)
425{
426 test_void_0();
427 test_int_0();
428 test_void_1();
429 test_int_1();
430 test_void_2();
431 test_int_2();
432
433 return 0;
434}
435

source code of libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp