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