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 F, class A> function(allocator_arg_t, const A&, F); 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 29 #if TEST_STD_VER >= 11 30 struct RValueCallable { 31 template <class ...Args> 32 void operator()(Args&&...) && {} 33 }; 34 struct LValueCallable { 35 template <class ...Args> 36 void operator()(Args&&...) & {} 37 }; 38 #endif 39 40 class DummyClass {}; 41 42 template <class FuncType, class AllocType> 43 void test_FunctionObject(AllocType& alloc) 44 { 45 assert(globalMemCounter.checkOutstandingNewEq(0)); 46 { 47 FunctionObject target; 48 assert(FunctionObject::count == 1); 49 assert(globalMemCounter.checkOutstandingNewEq(0)); 50 std::function<FuncType> f2(std::allocator_arg, alloc, target); 51 assert(FunctionObject::count == 2); 52 assert(globalMemCounter.checkOutstandingNewEq(1)); 53 assert(f2.template target<FunctionObject>()); 54 assert(f2.template target<FuncType>() == 0); 55 assert(f2.template target<FuncType*>() == 0); 56 } 57 assert(FunctionObject::count == 0); 58 assert(globalMemCounter.checkOutstandingNewEq(0)); 59 } 60 61 62 template <class FuncType, class AllocType> 63 void test_FreeFunction(AllocType& alloc) 64 { 65 assert(globalMemCounter.checkOutstandingNewEq(0)); 66 { 67 FuncType* target = &FreeFunction; 68 assert(globalMemCounter.checkOutstandingNewEq(0)); 69 std::function<FuncType> f2(std::allocator_arg, alloc, target); 70 // The allocator may not fit in the small object buffer, if we allocated 71 // check it was done via the allocator. 72 assert(globalMemCounter.checkOutstandingNewEq(test_alloc_base::alloc_count)); 73 assert(f2.template target<FuncType*>()); 74 assert(*f2.template target<FuncType*>() == target); 75 assert(f2.template target<FuncType>() == 0); 76 assert(f2.template target<DummyClass>() == 0); 77 } 78 assert(globalMemCounter.checkOutstandingNewEq(0)); 79 } 80 81 template <class TargetType, class FuncType, class AllocType> 82 void test_MemFunClass(AllocType& alloc) 83 { 84 assert(globalMemCounter.checkOutstandingNewEq(0)); 85 { 86 TargetType target = &MemFunClass::foo; 87 assert(globalMemCounter.checkOutstandingNewEq(0)); 88 std::function<FuncType> f2(std::allocator_arg, alloc, target); 89 assert(globalMemCounter.checkOutstandingNewEq(test_alloc_base::alloc_count)); 90 assert(f2.template target<TargetType>()); 91 assert(*f2.template target<TargetType>() == target); 92 assert(f2.template target<FuncType*>() == 0); 93 } 94 assert(globalMemCounter.checkOutstandingNewEq(0)); 95 } 96 97 template <class Alloc> 98 void test_for_alloc(Alloc& alloc) { 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 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 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 globalMemCounter.reset(); 117 { 118 bare_allocator<DummyClass> bare_alloc; 119 test_for_alloc(bare_alloc); 120 } 121 { 122 non_default_test_allocator<DummyClass> non_default_alloc(42); 123 test_for_alloc(non_default_alloc); 124 } 125 #if TEST_STD_VER >= 11 126 { 127 using Fn = std::function<void(int, int, int)>; 128 static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, ""); 129 static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, ""); 130 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, ""); 131 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, ""); 132 } 133 #endif 134 135 136 return 0; 137 } 138