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 #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.hpp" 23 #include "../function_types.h" 24 25 26 #if TEST_STD_VER >= 11 27 struct RValueCallable { 28 template <class ...Args> 29 void operator()(Args&&...) && {} 30 }; 31 struct LValueCallable { 32 template <class ...Args> 33 void operator()(Args&&...) & {} 34 }; 35 #endif 36 37 class DummyClass {}; 38 39 template <class FuncType, class AllocType> 40 void test_FunctionObject(AllocType& alloc) 41 { 42 assert(globalMemCounter.checkOutstandingNewEq(0)); 43 { 44 FunctionObject target; 45 assert(FunctionObject::count == 1); 46 assert(globalMemCounter.checkOutstandingNewEq(0)); 47 std::function<FuncType> f2(std::allocator_arg, alloc, target); 48 assert(FunctionObject::count == 2); 49 assert(globalMemCounter.checkOutstandingNewEq(1)); 50 assert(f2.template target<FunctionObject>()); 51 assert(f2.template target<FuncType>() == 0); 52 assert(f2.template target<FuncType*>() == 0); 53 } 54 assert(FunctionObject::count == 0); 55 assert(globalMemCounter.checkOutstandingNewEq(0)); 56 } 57 58 59 template <class FuncType, class AllocType> 60 void test_FreeFunction(AllocType& alloc) 61 { 62 assert(globalMemCounter.checkOutstandingNewEq(0)); 63 { 64 FuncType* target = &FreeFunction; 65 assert(globalMemCounter.checkOutstandingNewEq(0)); 66 std::function<FuncType> f2(std::allocator_arg, alloc, target); 67 assert(globalMemCounter.checkOutstandingNewEq(0)); 68 assert(f2.template target<FuncType*>()); 69 assert(*f2.template target<FuncType*>() == target); 70 assert(f2.template target<FuncType>() == 0); 71 assert(f2.template target<DummyClass>() == 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 TargetType target = &MemFunClass::foo; 82 assert(globalMemCounter.checkOutstandingNewEq(0)); 83 std::function<FuncType> f2(std::allocator_arg, alloc, target); 84 assert(globalMemCounter.checkOutstandingNewEq(0)); 85 assert(f2.template target<TargetType>()); 86 assert(*f2.template target<TargetType>() == target); 87 assert(f2.template target<FuncType*>() == 0); 88 } 89 assert(globalMemCounter.checkOutstandingNewEq(0)); 90 } 91 92 template <class Alloc> 93 void test_for_alloc(Alloc& alloc) { 94 test_FunctionObject<int()>(alloc); 95 test_FunctionObject<int(int)>(alloc); 96 test_FunctionObject<int(int, int)>(alloc); 97 test_FunctionObject<int(int, int, int)>(alloc); 98 99 test_FreeFunction<int()>(alloc); 100 test_FreeFunction<int(int)>(alloc); 101 test_FreeFunction<int(int, int)>(alloc); 102 test_FreeFunction<int(int, int, int)>(alloc); 103 104 test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc); 105 test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc); 106 test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc); 107 } 108 109 int main(int, char**) 110 { 111 { 112 bare_allocator<DummyClass> bare_alloc; 113 test_for_alloc(bare_alloc); 114 } 115 { 116 non_default_test_allocator<DummyClass> non_default_alloc(42); 117 test_for_alloc(non_default_alloc); 118 } 119 #if TEST_STD_VER >= 11 120 { 121 using Fn = std::function<void(int, int, int)>; 122 static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, ""); 123 static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, ""); 124 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, ""); 125 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, ""); 126 } 127 #endif 128 129 130 return 0; 131 } 132