200 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++0310 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 24class A {25 int data_[10];26 27public: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 56int A::count = 0;57 58int g0() { return 0; }59int g(int) { return 0; }60int h(int) { return 1; }61int g2(int, int) { return 2; }62int g3(int, int, int) { return 3; }63 64int 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.checkOutstandingNewLessThanOrEqual(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.checkOutstandingNewLessThanOrEqual(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.checkOutstandingNewLessThanOrEqual(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.checkOutstandingNewLessThanOrEqual(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.checkOutstandingNewLessThanOrEqual(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.checkOutstandingNewLessThanOrEqual(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