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