//===----------------------------------------------------------------------===// // // 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&, F); #include #include #include "test_macros.h" #include "min_allocator.h" #include "test_allocator.h" #include "count_new.h" #include "../function_types.h" #if TEST_STD_VER >= 11 struct RValueCallable { template void operator()(Args&&...) && {} }; struct LValueCallable { template void operator()(Args&&...) & {} }; #endif template struct non_default_test_allocator : test_allocator { non_default_test_allocator() = delete; using test_allocator::test_allocator; }; test_allocator_statistics alloc_stats; class DummyClass {}; template void test_FunctionObject(AllocType& alloc) { assert(globalMemCounter.checkOutstandingNewEq(0)); { FunctionObject target; assert(FunctionObject::count == 1); assert(globalMemCounter.checkOutstandingNewEq(0)); std::function f2(std::allocator_arg, alloc, target); assert(FunctionObject::count == 2); assert(globalMemCounter.checkOutstandingNewEq(1)); assert(f2.template target()); assert(f2.template target() == 0); assert(f2.template target() == 0); } assert(FunctionObject::count == 0); assert(globalMemCounter.checkOutstandingNewEq(0)); } template void test_FreeFunction(AllocType& alloc) { assert(globalMemCounter.checkOutstandingNewEq(0)); { FuncType* target = &FreeFunction; assert(globalMemCounter.checkOutstandingNewEq(0)); std::function f2(std::allocator_arg, alloc, target); // The allocator may not fit in the small object buffer, if we allocated // check it was done via the allocator. assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count)); assert(f2.template target()); assert(*f2.template target() == target); assert(f2.template target() == 0); assert(f2.template target() == 0); } assert(globalMemCounter.checkOutstandingNewEq(0)); } template void test_MemFunClass(AllocType& alloc) { assert(globalMemCounter.checkOutstandingNewEq(0)); { TargetType target = &MemFunClass::foo; assert(globalMemCounter.checkOutstandingNewEq(0)); std::function f2(std::allocator_arg, alloc, target); assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count)); assert(f2.template target()); assert(*f2.template target() == target); assert(f2.template target() == 0); } assert(globalMemCounter.checkOutstandingNewEq(0)); } template void test_for_alloc(Alloc& alloc) { test_FunctionObject(alloc); test_FunctionObject(alloc); test_FunctionObject(alloc); test_FunctionObject(alloc); test_FreeFunction(alloc); test_FreeFunction(alloc); test_FreeFunction(alloc); test_FreeFunction(alloc); test_MemFunClass(alloc); test_MemFunClass(alloc); test_MemFunClass(alloc); } int main(int, char**) { globalMemCounter.reset(); { bare_allocator bare_alloc; test_for_alloc(bare_alloc); } { non_default_test_allocator non_default_alloc(42, &alloc_stats); test_for_alloc(non_default_alloc); } #if TEST_STD_VER >= 11 { using Fn = std::function; static_assert(std::is_constructible, LValueCallable&>::value, ""); static_assert(std::is_constructible, LValueCallable>::value, ""); static_assert(!std::is_constructible, RValueCallable&>::value, ""); static_assert(!std::is_constructible, RValueCallable>::value, ""); } #endif return 0; }