1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <functional> 11 // REQUIRES: c++98 || c++03 || c++11 ||c++14 12 13 // class function<R(ArgTypes...)> 14 15 // template<class F, class A> function(allocator_arg_t, const A&, F); 16 17 #include <functional> 18 #include <cassert> 19 20 #include "test_macros.h" 21 #include "min_allocator.h" 22 #include "test_allocator.h" 23 #include "count_new.hpp" 24 #include "../function_types.h" 25 26 27 #if TEST_STD_VER >= 11 28 struct RValueCallable { 29 template <class ...Args> 30 void operator()(Args&&...) && {} 31 }; 32 struct LValueCallable { 33 template <class ...Args> 34 void operator()(Args&&...) & {} 35 }; 36 #endif 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 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 assert(f2.template target<DummyClass>() == 0); 73 } 74 assert(globalMemCounter.checkOutstandingNewEq(0)); 75 } 76 77 template <class TargetType, class FuncType, class AllocType> 78 void test_MemFunClass(AllocType& alloc) 79 { 80 assert(globalMemCounter.checkOutstandingNewEq(0)); 81 { 82 TargetType target = &MemFunClass::foo; 83 assert(globalMemCounter.checkOutstandingNewEq(0)); 84 std::function<FuncType> f2(std::allocator_arg, alloc, target); 85 assert(globalMemCounter.checkOutstandingNewEq(0)); 86 assert(f2.template target<TargetType>()); 87 assert(*f2.template target<TargetType>() == target); 88 assert(f2.template target<FuncType*>() == 0); 89 } 90 assert(globalMemCounter.checkOutstandingNewEq(0)); 91 } 92 93 template <class Alloc> 94 void test_for_alloc(Alloc& alloc) { 95 test_FunctionObject<int()>(alloc); 96 test_FunctionObject<int(int)>(alloc); 97 test_FunctionObject<int(int, int)>(alloc); 98 test_FunctionObject<int(int, int, int)>(alloc); 99 100 test_FreeFunction<int()>(alloc); 101 test_FreeFunction<int(int)>(alloc); 102 test_FreeFunction<int(int, int)>(alloc); 103 test_FreeFunction<int(int, int, int)>(alloc); 104 105 test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc); 106 test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc); 107 test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc); 108 } 109 110 int main() 111 { 112 { 113 bare_allocator<DummyClass> bare_alloc; 114 test_for_alloc(bare_alloc); 115 } 116 { 117 non_default_test_allocator<DummyClass> non_default_alloc(42); 118 test_for_alloc(non_default_alloc); 119 } 120 #if TEST_STD_VER >= 11 121 { 122 using Fn = std::function<void(int, int, int)>; 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>, LValueCallable>::value, ""); 125 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, ""); 126 static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, ""); 127 } 128 #endif 129 130 } 131