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