xref: /llvm-project/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/invoke.pass.cpp (revision 2df59c50688c122bbcae7467d3eaf862c3ea3088)
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 // <functional>
10 
11 // reference_wrapper
12 
13 // template <class... ArgTypes>
14 //   requires Callable<T, ArgTypes&&...>
15 //   Callable<T, ArgTypes&&...>::result_type
16 //   operator()(ArgTypes&&... args) const;
17 
18 #include <functional>
19 #include <cassert>
20 
21 int count = 0;
22 
23 // 1 arg, return void
24 
25 void f_void_1(int i)
26 {
27     count += i;
28 }
29 
30 struct A_void_1
31 {
32     void operator()(int i)
33     {
34         count += i;
35     }
36 
37     void mem1() {++count;}
38     void mem2() const {++count;}
39 };
40 
41 void
42 test_void_1()
43 {
44     int save_count = count;
45     // function
46     {
47     std::reference_wrapper<void (int)> r1(f_void_1);
48     int i = 2;
49     r1(i);
50     assert(count == save_count+2);
51     save_count = count;
52     }
53     // function pointer
54     {
55     void (*fp)(int) = f_void_1;
56     std::reference_wrapper<void (*)(int)> r1(fp);
57     int i = 3;
58     r1(i);
59     assert(count == save_count+3);
60     save_count = count;
61     }
62     // functor
63     {
64     A_void_1 a0;
65     std::reference_wrapper<A_void_1> r1(a0);
66     int i = 4;
67     r1(i);
68     assert(count == save_count+4);
69     save_count = count;
70     }
71     // member function pointer
72     {
73     void (A_void_1::*fp)() = &A_void_1::mem1;
74     std::reference_wrapper<void (A_void_1::*)()> r1(fp);
75     A_void_1 a;
76     r1(a);
77     assert(count == save_count+1);
78     save_count = count;
79     A_void_1* ap = &a;
80     r1(ap);
81     assert(count == save_count+1);
82     save_count = count;
83     }
84     // const member function pointer
85     {
86     void (A_void_1::*fp)() const = &A_void_1::mem2;
87     std::reference_wrapper<void (A_void_1::*)() const> r1(fp);
88     A_void_1 a;
89     r1(a);
90     assert(count == save_count+1);
91     save_count = count;
92     A_void_1* ap = &a;
93     r1(ap);
94     assert(count == save_count+1);
95     save_count = count;
96     }
97 }
98 
99 // 1 arg, return int
100 
101 int f_int_1(int i)
102 {
103     return i + 1;
104 }
105 
106 struct A_int_1
107 {
108     A_int_1() : data_(5) {}
109     int operator()(int i)
110     {
111         return i - 1;
112     }
113 
114     int mem1() {return 3;}
115     int mem2() const {return 4;}
116     int data_;
117 };
118 
119 void
120 test_int_1()
121 {
122     // function
123     {
124     std::reference_wrapper<int (int)> r1(f_int_1);
125     int i = 2;
126     assert(r1(i) == 3);
127     }
128     // function pointer
129     {
130     int (*fp)(int) = f_int_1;
131     std::reference_wrapper<int (*)(int)> r1(fp);
132     int i = 3;
133     assert(r1(i) == 4);
134     }
135     // functor
136     {
137     A_int_1 a0;
138     std::reference_wrapper<A_int_1> r1(a0);
139     int i = 4;
140     assert(r1(i) == 3);
141     }
142     // member function pointer
143     {
144     int (A_int_1::*fp)() = &A_int_1::mem1;
145     std::reference_wrapper<int (A_int_1::*)()> r1(fp);
146     A_int_1 a;
147     assert(r1(a) == 3);
148     A_int_1* ap = &a;
149     assert(r1(ap) == 3);
150     }
151     // const member function pointer
152     {
153     int (A_int_1::*fp)() const = &A_int_1::mem2;
154     std::reference_wrapper<int (A_int_1::*)() const> r1(fp);
155     A_int_1 a;
156     assert(r1(a) == 4);
157     A_int_1* ap = &a;
158     assert(r1(ap) == 4);
159     }
160     // member data pointer
161     {
162     int A_int_1::*fp = &A_int_1::data_;
163     std::reference_wrapper<int A_int_1::*> r1(fp);
164     A_int_1 a;
165     assert(r1(a) == 5);
166     r1(a) = 6;
167     assert(r1(a) == 6);
168     A_int_1* ap = &a;
169     assert(r1(ap) == 6);
170     r1(ap) = 7;
171     assert(r1(ap) == 7);
172     }
173 }
174 
175 // 2 arg, return void
176 
177 void f_void_2(int i, int j)
178 {
179     count += i+j;
180 }
181 
182 struct A_void_2
183 {
184     void operator()(int i, int j)
185     {
186         count += i+j;
187     }
188 
189     void mem1(int i) {count += i;}
190     void mem2(int i) const {count += i;}
191 };
192 
193 void
194 test_void_2()
195 {
196     int save_count = count;
197     // function
198     {
199     std::reference_wrapper<void (int, int)> r1(f_void_2);
200     int i = 2;
201     int j = 3;
202     r1(i, j);
203     assert(count == save_count+5);
204     save_count = count;
205     }
206     // function pointer
207     {
208     void (*fp)(int, int) = f_void_2;
209     std::reference_wrapper<void (*)(int, int)> r1(fp);
210     int i = 3;
211     int j = 4;
212     r1(i, j);
213     assert(count == save_count+7);
214     save_count = count;
215     }
216     // functor
217     {
218     A_void_2 a0;
219     std::reference_wrapper<A_void_2> r1(a0);
220     int i = 4;
221     int j = 5;
222     r1(i, j);
223     assert(count == save_count+9);
224     save_count = count;
225     }
226     // member function pointer
227     {
228     void (A_void_2::*fp)(int) = &A_void_2::mem1;
229     std::reference_wrapper<void (A_void_2::*)(int)> r1(fp);
230     A_void_2 a;
231     int i = 3;
232     r1(a, i);
233     assert(count == save_count+3);
234     save_count = count;
235     A_void_2* ap = &a;
236     r1(ap, i);
237     assert(count == save_count+3);
238     save_count = count;
239     }
240     // const member function pointer
241     {
242     void (A_void_2::*fp)(int) const = &A_void_2::mem2;
243     std::reference_wrapper<void (A_void_2::*)(int) const> r1(fp);
244     A_void_2 a;
245     int i = 4;
246     r1(a, i);
247     assert(count == save_count+4);
248     save_count = count;
249     A_void_2* ap = &a;
250     r1(ap, i);
251     assert(count == save_count+4);
252     save_count = count;
253     }
254 }
255 
256 // 2 arg, return int
257 
258 int f_int_2(int i, int j)
259 {
260     return i+j;
261 }
262 
263 struct A_int_2
264 {
265     int operator()(int i, int j)
266     {
267         return i+j;
268     }
269 
270     int mem1(int i) {return i+1;}
271     int mem2(int i) const {return i+2;}
272 };
273 
274 void
275 testint_2()
276 {
277     // function
278     {
279     std::reference_wrapper<int (int, int)> r1(f_int_2);
280     int i = 2;
281     int j = 3;
282     assert(r1(i, j) == i+j);
283     }
284     // function pointer
285     {
286     int (*fp)(int, int) = f_int_2;
287     std::reference_wrapper<int (*)(int, int)> r1(fp);
288     int i = 3;
289     int j = 4;
290     assert(r1(i, j) == i+j);
291     }
292     // functor
293     {
294     A_int_2 a0;
295     std::reference_wrapper<A_int_2> r1(a0);
296     int i = 4;
297     int j = 5;
298     assert(r1(i, j) == i+j);
299     }
300     // member function pointer
301     {
302     int(A_int_2::*fp)(int) = &A_int_2::mem1;
303     std::reference_wrapper<int (A_int_2::*)(int)> r1(fp);
304     A_int_2 a;
305     int i = 3;
306     assert(r1(a, i) == i+1);
307     A_int_2* ap = &a;
308     assert(r1(ap, i) == i+1);
309     }
310     // const member function pointer
311     {
312     int (A_int_2::*fp)(int) const = &A_int_2::mem2;
313     std::reference_wrapper<int (A_int_2::*)(int) const> r1(fp);
314     A_int_2 a;
315     int i = 4;
316     assert(r1(a, i) == i+2);
317     A_int_2* ap = &a;
318     assert(r1(ap, i) == i+2);
319     }
320 }
321 
322 int main(int, char**)
323 {
324     test_void_1();
325     test_int_1();
326     test_void_2();
327     testint_2();
328 
329   return 0;
330 }
331