//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // REQUIRES: c++11 || c++14 // class function // template function(allocator_arg_t, const A&, const function&); #include #include #include "test_macros.h" #include "min_allocator.h" #include "test_allocator.h" #include "count_new.h" #include "../function_types.h" template struct non_default_test_allocator : test_allocator { non_default_test_allocator() = delete; using test_allocator::test_allocator; }; class DummyClass {}; template void test_FunctionObject(AllocType& alloc) { assert(globalMemCounter.checkOutstandingNewEq(0)); { // Construct function from FunctionObject. std::function f = FunctionObject(); assert(FunctionObject::count == 1); assert(globalMemCounter.checkOutstandingNewEq(1)); RTTI_ASSERT(f.template target()); RTTI_ASSERT(f.template target() == 0); RTTI_ASSERT(f.template target() == 0); // Copy function with allocator std::function f2(std::allocator_arg, alloc, f); assert(FunctionObject::count == 2); assert(globalMemCounter.checkOutstandingNewEq(2)); RTTI_ASSERT(f2.template target()); RTTI_ASSERT(f2.template target() == 0); RTTI_ASSERT(f2.template target() == 0); } assert(FunctionObject::count == 0); assert(globalMemCounter.checkOutstandingNewEq(0)); } template void test_FreeFunction(AllocType& alloc) { assert(globalMemCounter.checkOutstandingNewEq(0)); { // Construct function from function pointer. FuncType* target = &FreeFunction; std::function f = target; assert(globalMemCounter.checkOutstandingNewEq(0)); RTTI_ASSERT(f.template target()); RTTI_ASSERT(*f.template target() == target); RTTI_ASSERT(f.template target() == 0); // Copy function with allocator std::function f2(std::allocator_arg, alloc, f); assert(globalMemCounter.checkOutstandingNewEq(0)); RTTI_ASSERT(f2.template target()); RTTI_ASSERT(*f2.template target() == target); RTTI_ASSERT(f2.template target() == 0); } assert(globalMemCounter.checkOutstandingNewEq(0)); } template void test_MemFunClass(AllocType& alloc) { assert(globalMemCounter.checkOutstandingNewEq(0)); { // Construct function from function pointer. TargetType target = &MemFunClass::foo; std::function f = target; assert(globalMemCounter.checkOutstandingNewEq(0)); RTTI_ASSERT(f.template target()); RTTI_ASSERT(*f.template target() == target); RTTI_ASSERT(f.template target() == 0); // Copy function with allocator std::function f2(std::allocator_arg, alloc, f); assert(globalMemCounter.checkOutstandingNewEq(0)); RTTI_ASSERT(f2.template target()); RTTI_ASSERT(*f2.template target() == target); RTTI_ASSERT(f2.template target() == 0); } assert(globalMemCounter.checkOutstandingNewEq(0)); } template void test_for_alloc(Alloc& alloc) { // Large FunctionObject -- Allocation should occur test_FunctionObject(alloc); test_FunctionObject(alloc); test_FunctionObject(alloc); test_FunctionObject(alloc); // Free function -- No allocation should occur test_FreeFunction(alloc); test_FreeFunction(alloc); test_FreeFunction(alloc); test_FreeFunction(alloc); // Member function -- No allocation should occur. test_MemFunClass(alloc); test_MemFunClass(alloc); test_MemFunClass(alloc); } int main(int, char**) { globalMemCounter.reset(); { bare_allocator alloc; test_for_alloc(alloc); } { non_default_test_allocator alloc(42); test_for_alloc(alloc); } return 0; }