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++11 || c++14 11 12 // class function<R(ArgTypes...)> 13 14 // template<class F, class A> function(allocator_arg_t, const A&, F); 15 16 #include <functional> 17 #include <cassert> 18 19 #include "test_macros.h" 20 #include "min_allocator.h" 21 #include "test_allocator.h" 22 #include "count_new.h" 23 #include "../function_types.h" 24 25 #if TEST_STD_VER >= 11 26 struct RValueCallable { 27 template <class ...Args> 28 void operator()(Args&&...) && {} 29 }; 30 struct LValueCallable { 31 template <class ...Args> 32 void operator()(Args&&...) & {} 33 }; 34 #endif 35 36 test_allocator_statistics alloc_stats; 37 38 class DummyClass {}; 39 40 template <class FuncType, class AllocType> 41 void test_FunctionObject(AllocType& alloc) 42 { 43 assert(globalMemCounter.checkOutstandingNewEq(0)); 44 { 45 FunctionObject target; 46 assert(FunctionObject::count == 1); 47 assert(globalMemCounter.checkOutstandingNewEq(0)); 48 std::function<FuncType> f2(std::allocator_arg, alloc, target); 49 assert(FunctionObject::count == 2); 50 assert(globalMemCounter.checkOutstandingNewEq(1)); 51 assert(f2.template target<FunctionObject>()); 52 assert(f2.template target<FuncType>() == 0); 53 assert(f2.template target<FuncType*>() == 0); 54 } 55 assert(FunctionObject::count == 0); 56 assert(globalMemCounter.checkOutstandingNewEq(0)); 57 } 58 59 60 template <class FuncType, class AllocType> 61 void test_FreeFunction(AllocType& alloc) 62 { 63 assert(globalMemCounter.checkOutstandingNewEq(0)); 64 { 65 FuncType* target = &FreeFunction; 66 assert(globalMemCounter.checkOutstandingNewEq(0)); 67 std::function<FuncType> f2(std::allocator_arg, alloc, target); 68 // The allocator may not fit in the small object buffer, if we allocated 69 // check it was done via the allocator. 70 assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count)); 71 assert(f2.template target<FuncType*>()); 72 assert(*f2.template target<FuncType*>() == target); 73 assert(f2.template target<FuncType>() == 0); 74 assert(f2.template target<DummyClass>() == 0); 75 } 76 assert(globalMemCounter.checkOutstandingNewEq(0)); 77 } 78 79 template <class TargetType, class FuncType, class AllocType> 80 void test_MemFunClass(AllocType& alloc) 81 { 82 assert(globalMemCounter.checkOutstandingNewEq(0)); 83 { 84 TargetType target = &MemFunClass::foo; 85 assert(globalMemCounter.checkOutstandingNewEq(0)); 86 std::function<FuncType> f2(std::allocator_arg, alloc, target); 87 assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count)); 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 test_FunctionObject<int()>(alloc); 98 test_FunctionObject<int(int)>(alloc); 99 test_FunctionObject<int(int, int)>(alloc); 100 test_FunctionObject<int(int, int, int)>(alloc); 101 102 test_FreeFunction<int()>(alloc); 103 test_FreeFunction<int(int)>(alloc); 104 test_FreeFunction<int(int, int)>(alloc); 105 test_FreeFunction<int(int, int, int)>(alloc); 106 107 test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc); 108 test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc); 109 test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc); 110 } 111 112 int main(int, char**) { 113 globalMemCounter.reset(); 114 { 115 bare_allocator<DummyClass> bare_alloc; 116 test_for_alloc(bare_alloc); 117 } 118 { 119 non_default_test_allocator<DummyClass> non_default_alloc(42, &alloc_stats); 120 test_for_alloc(non_default_alloc); 121 } 122 #if TEST_STD_VER >= 11 123 { 124 using Fn = std::function<void(int, int, int)>; 125 static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, ""); 126 static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, ""); 127 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, ""); 128 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, ""); 129 } 130 #endif 131 132 133 return 0; 134 } 135