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 // class function<R(ArgTypes...)>
13 
14 // void swap(function& other);
15 
16 #include <functional>
17 #include <cassert>
18 
19 #include "count_new.hpp"
20 
21 class A {
22   int data_[10];
23 
24 public:
25   static int count;
26 
A(int j)27   explicit A(int j) {
28     ++count;
29     data_[0] = j;
30   }
31 
A(const A & a)32   A(const A &a) {
33     ++count;
34     for (int i = 0; i < 10; ++i)
35       data_[i] = a.data_[i];
36   }
37 
~A()38   ~A() { --count; }
39 
operator ()(int i) const40   int operator()(int i) const {
41     for (int j = 0; j < 10; ++j)
42       i += data_[j];
43     return i;
44   }
45 
operator ()() const46   int operator()() const { return -1; }
operator ()(int,int) const47   int operator()(int, int) const { return -2; }
operator ()(int,int,int) const48   int operator()(int, int, int) const { return -3; }
49 
id() const50   int id() const { return data_[0]; }
51 };
52 
53 int A::count = 0;
54 
g0()55 int g0() { return 0; }
g(int)56 int g(int) { return 0; }
h(int)57 int h(int) { return 1; }
g2(int,int)58 int g2(int, int) { return 2; }
g3(int,int,int)59 int g3(int, int, int) { return 3; }
60 
main()61 int main() {
62   assert(globalMemCounter.checkOutstandingNewEq(0));
63   {
64     std::function<int(int)> f1 = A(1);
65     std::function<int(int)> f2 = A(2);
66     assert(A::count == 2);
67     assert(globalMemCounter.checkOutstandingNewEq(2));
68     assert(f1.target<A>()->id() == 1);
69     assert(f2.target<A>()->id() == 2);
70     f1.swap(f2);
71     assert(A::count == 2);
72     assert(globalMemCounter.checkOutstandingNewEq(2));
73     assert(f1.target<A>()->id() == 2);
74     assert(f2.target<A>()->id() == 1);
75   }
76   assert(A::count == 0);
77   assert(globalMemCounter.checkOutstandingNewEq(0));
78   {
79     std::function<int(int)> f1 = A(1);
80     std::function<int(int)> f2 = g;
81     assert(A::count == 1);
82     assert(globalMemCounter.checkOutstandingNewEq(1));
83     assert(f1.target<A>()->id() == 1);
84     assert(*f2.target<int (*)(int)>() == g);
85     f1.swap(f2);
86     assert(A::count == 1);
87     assert(globalMemCounter.checkOutstandingNewEq(1));
88     assert(*f1.target<int (*)(int)>() == g);
89     assert(f2.target<A>()->id() == 1);
90   }
91   assert(A::count == 0);
92   assert(globalMemCounter.checkOutstandingNewEq(0));
93   {
94     std::function<int(int)> f1 = g;
95     std::function<int(int)> f2 = A(1);
96     assert(A::count == 1);
97     assert(globalMemCounter.checkOutstandingNewEq(1));
98     assert(*f1.target<int (*)(int)>() == g);
99     assert(f2.target<A>()->id() == 1);
100     f1.swap(f2);
101     assert(A::count == 1);
102     assert(globalMemCounter.checkOutstandingNewEq(1));
103     assert(f1.target<A>()->id() == 1);
104     assert(*f2.target<int (*)(int)>() == g);
105   }
106   assert(A::count == 0);
107   assert(globalMemCounter.checkOutstandingNewEq(0));
108   {
109     std::function<int(int)> f1 = g;
110     std::function<int(int)> f2 = h;
111     assert(A::count == 0);
112     assert(globalMemCounter.checkOutstandingNewEq(0));
113     assert(*f1.target<int (*)(int)>() == g);
114     assert(*f2.target<int (*)(int)>() == h);
115     f1.swap(f2);
116     assert(A::count == 0);
117     assert(globalMemCounter.checkOutstandingNewEq(0));
118     assert(*f1.target<int (*)(int)>() == h);
119     assert(*f2.target<int (*)(int)>() == g);
120   }
121   assert(A::count == 0);
122   assert(globalMemCounter.checkOutstandingNewEq(0));
123   {
124     std::function<int(int)> f1 = A(1);
125     assert(A::count == 1);
126     {
127       DisableAllocationGuard guard;
128       ((void)guard);
129       f1.swap(f1);
130     }
131     assert(A::count == 1);
132     assert(f1.target<A>()->id() == 1);
133   }
134   assert(A::count == 0);
135   assert(globalMemCounter.checkOutstandingNewEq(0));
136   {
137     std::function<int()> f1 = g0;
138     DisableAllocationGuard guard;
139     ((void)guard);
140     f1.swap(f1);
141     assert(*f1.target<int (*)()>() == g0);
142   }
143   assert(globalMemCounter.checkOutstandingNewEq(0));
144   {
145     std::function<int(int, int)> f1 = g2;
146     DisableAllocationGuard guard;
147     ((void)guard);
148     f1.swap(f1);
149     assert(*f1.target<int (*)(int, int)>() == g2);
150   }
151   assert(globalMemCounter.checkOutstandingNewEq(0));
152   {
153     std::function<int(int, int, int)> f1 = g3;
154     DisableAllocationGuard guard;
155     ((void)guard);
156     f1.swap(f1);
157     assert(*f1.target<int (*)(int, int, int)>() == g3);
158   }
159   assert(globalMemCounter.checkOutstandingNewEq(0));
160   {
161     std::function<int()> f1 = A(1);
162     assert(A::count == 1);
163     DisableAllocationGuard guard;
164     ((void)guard);
165     f1.swap(f1);
166     assert(A::count == 1);
167     assert(f1.target<A>()->id() == 1);
168   }
169   assert(globalMemCounter.checkOutstandingNewEq(0));
170   assert(A::count == 0);
171   {
172     std::function<int(int, int)> f1 = A(2);
173     assert(A::count == 1);
174     DisableAllocationGuard guard;
175     ((void)guard);
176     f1.swap(f1);
177     assert(A::count == 1);
178     assert(f1.target<A>()->id() == 2);
179   }
180   assert(globalMemCounter.checkOutstandingNewEq(0));
181   assert(A::count == 0);
182   {
183     std::function<int(int, int, int)> f1 = A(3);
184     assert(A::count == 1);
185     DisableAllocationGuard guard;
186     ((void)guard);
187     f1.swap(f1);
188     assert(A::count == 1);
189     assert(f1.target<A>()->id() == 3);
190   }
191   assert(globalMemCounter.checkOutstandingNewEq(0));
192   assert(A::count == 0);
193 }
194