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 // <functional> 10 // REQUIRES: c++03 || c++11 || c++14 11 12 // class function<R(ArgTypes...)> 13 14 // template<class A> function(allocator_arg_t, const A&, const function&); 15 16 // This test runs in C++03, but we have deprecated using std::function in C++03. 17 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS 18 19 #include <functional> 20 #include <cassert> 21 22 #include "test_macros.h" 23 #include "min_allocator.h" 24 #include "test_allocator.h" 25 #include "count_new.h" 26 #include "../function_types.h" 27 28 class DummyClass {}; 29 30 template <class FuncType, class AllocType> 31 void test_FunctionObject(AllocType& alloc) 32 { 33 assert(globalMemCounter.checkOutstandingNewEq(0)); 34 { 35 // Construct function from FunctionObject. 36 std::function<FuncType> f = FunctionObject(); 37 assert(FunctionObject::count == 1); 38 assert(globalMemCounter.checkOutstandingNewEq(1)); 39 assert(f.template target<FunctionObject>()); 40 assert(f.template target<FuncType>() == 0); 41 assert(f.template target<FuncType*>() == 0); 42 // Copy function with allocator 43 std::function<FuncType> f2(std::allocator_arg, alloc, f); 44 assert(FunctionObject::count == 2); 45 assert(globalMemCounter.checkOutstandingNewEq(2)); 46 assert(f2.template target<FunctionObject>()); 47 assert(f2.template target<FuncType>() == 0); 48 assert(f2.template target<FuncType*>() == 0); 49 } 50 assert(FunctionObject::count == 0); 51 assert(globalMemCounter.checkOutstandingNewEq(0)); 52 } 53 54 template <class FuncType, class AllocType> 55 void test_FreeFunction(AllocType& alloc) 56 { 57 assert(globalMemCounter.checkOutstandingNewEq(0)); 58 { 59 // Construct function from function pointer. 60 FuncType* target = &FreeFunction; 61 std::function<FuncType> f = target; 62 assert(globalMemCounter.checkOutstandingNewEq(0)); 63 assert(f.template target<FuncType*>()); 64 assert(*f.template target<FuncType*>() == target); 65 assert(f.template target<FuncType>() == 0); 66 // Copy function with allocator 67 std::function<FuncType> f2(std::allocator_arg, alloc, f); 68 assert(globalMemCounter.checkOutstandingNewEq(0)); 69 assert(f2.template target<FuncType*>()); 70 assert(*f2.template target<FuncType*>() == target); 71 assert(f2.template target<FuncType>() == 0); 72 } 73 assert(globalMemCounter.checkOutstandingNewEq(0)); 74 } 75 76 template <class TargetType, class FuncType, class AllocType> 77 void test_MemFunClass(AllocType& alloc) 78 { 79 assert(globalMemCounter.checkOutstandingNewEq(0)); 80 { 81 // Construct function from function pointer. 82 TargetType target = &MemFunClass::foo; 83 std::function<FuncType> f = target; 84 assert(globalMemCounter.checkOutstandingNewEq(0)); 85 assert(f.template target<TargetType>()); 86 assert(*f.template target<TargetType>() == target); 87 assert(f.template target<FuncType*>() == 0); 88 // Copy function with allocator 89 std::function<FuncType> f2(std::allocator_arg, alloc, f); 90 assert(globalMemCounter.checkOutstandingNewEq(0)); 91 assert(f2.template target<TargetType>()); 92 assert(*f2.template target<TargetType>() == target); 93 assert(f2.template target<FuncType*>() == 0); 94 } 95 assert(globalMemCounter.checkOutstandingNewEq(0)); 96 } 97 98 template <class Alloc> 99 void test_for_alloc(Alloc& alloc) 100 { 101 // Large FunctionObject -- Allocation should occur 102 test_FunctionObject<int()>(alloc); 103 test_FunctionObject<int(int)>(alloc); 104 test_FunctionObject<int(int, int)>(alloc); 105 test_FunctionObject<int(int, int, int)>(alloc); 106 // Free function -- No allocation should occur 107 test_FreeFunction<int()>(alloc); 108 test_FreeFunction<int(int)>(alloc); 109 test_FreeFunction<int(int, int)>(alloc); 110 test_FreeFunction<int(int, int, int)>(alloc); 111 // Member function -- No allocation should occur. 112 test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc); 113 test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc); 114 test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc); 115 } 116 117 int main(int, char**) 118 { 119 globalMemCounter.reset(); 120 { 121 bare_allocator<DummyClass> alloc; 122 test_for_alloc(alloc); 123 } 124 { 125 non_default_test_allocator<DummyClass> alloc(42); 126 test_for_alloc(alloc); 127 } 128 129 return 0; 130 } 131