15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier
95a83710eSEric Fiselier // <functional>
1031cbe0f2SLouis Dionne // REQUIRES: c++03 || c++11 || c++14
115a83710eSEric Fiselier
125a83710eSEric Fiselier // class function<R(ArgTypes...)>
135a83710eSEric Fiselier
145a83710eSEric Fiselier // template<class F, class A> function(allocator_arg_t, const A&, F);
155a83710eSEric Fiselier
16b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
17*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
18b4fb705eSLouis Dionne
195a83710eSEric Fiselier #include <functional>
205a83710eSEric Fiselier #include <cassert>
215a83710eSEric Fiselier
22790df145SEric Fiselier #include "test_macros.h"
236d370568SEric Fiselier #include "min_allocator.h"
24b11df184SEric Fiselier #include "test_allocator.h"
25cc89063bSNico Weber #include "count_new.h"
26b11df184SEric Fiselier #include "../function_types.h"
275a83710eSEric Fiselier
28790df145SEric Fiselier #if TEST_STD_VER >= 11
29790df145SEric Fiselier struct RValueCallable {
30790df145SEric Fiselier template <class ...Args>
operator ()RValueCallable31790df145SEric Fiselier void operator()(Args&&...) && {}
32790df145SEric Fiselier };
33790df145SEric Fiselier struct LValueCallable {
34790df145SEric Fiselier template <class ...Args>
operator ()LValueCallable35790df145SEric Fiselier void operator()(Args&&...) & {}
36790df145SEric Fiselier };
37790df145SEric Fiselier #endif
38790df145SEric Fiselier
399a140a15SNikolas Klauser test_allocator_statistics alloc_stats;
409a140a15SNikolas Klauser
41b11df184SEric Fiselier class DummyClass {};
425a83710eSEric Fiselier
43b11df184SEric Fiselier template <class FuncType, class AllocType>
test_FunctionObject(AllocType & alloc)44b11df184SEric Fiselier void test_FunctionObject(AllocType& alloc)
455a83710eSEric Fiselier {
46b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
47b11df184SEric Fiselier {
48b11df184SEric Fiselier FunctionObject target;
49b11df184SEric Fiselier assert(FunctionObject::count == 1);
50b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
51b11df184SEric Fiselier std::function<FuncType> f2(std::allocator_arg, alloc, target);
52b11df184SEric Fiselier assert(FunctionObject::count == 2);
53b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(1));
54b11df184SEric Fiselier assert(f2.template target<FunctionObject>());
55b11df184SEric Fiselier assert(f2.template target<FuncType>() == 0);
56b11df184SEric Fiselier assert(f2.template target<FuncType*>() == 0);
57b11df184SEric Fiselier }
58b11df184SEric Fiselier assert(FunctionObject::count == 0);
59b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
605a83710eSEric Fiselier }
615a83710eSEric Fiselier
625a83710eSEric Fiselier
63b11df184SEric Fiselier template <class FuncType, class AllocType>
test_FreeFunction(AllocType & alloc)64b11df184SEric Fiselier void test_FreeFunction(AllocType& alloc)
655a83710eSEric Fiselier {
66b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
67b11df184SEric Fiselier {
68b11df184SEric Fiselier FuncType* target = &FreeFunction;
69b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
70b11df184SEric Fiselier std::function<FuncType> f2(std::allocator_arg, alloc, target);
71cdff3806SEric Fiselier // The allocator may not fit in the small object buffer, if we allocated
72cdff3806SEric Fiselier // check it was done via the allocator.
739a140a15SNikolas Klauser assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count));
74b11df184SEric Fiselier assert(f2.template target<FuncType*>());
75b11df184SEric Fiselier assert(*f2.template target<FuncType*>() == target);
76b11df184SEric Fiselier assert(f2.template target<FuncType>() == 0);
77b11df184SEric Fiselier assert(f2.template target<DummyClass>() == 0);
78b11df184SEric Fiselier }
79b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
805a83710eSEric Fiselier }
815a83710eSEric Fiselier
82b11df184SEric Fiselier template <class TargetType, class FuncType, class AllocType>
test_MemFunClass(AllocType & alloc)83b11df184SEric Fiselier void test_MemFunClass(AllocType& alloc)
84b11df184SEric Fiselier {
85b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
86b11df184SEric Fiselier {
87b11df184SEric Fiselier TargetType target = &MemFunClass::foo;
88b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
89b11df184SEric Fiselier std::function<FuncType> f2(std::allocator_arg, alloc, target);
909a140a15SNikolas Klauser assert(globalMemCounter.checkOutstandingNewEq(alloc_stats.alloc_count));
91b11df184SEric Fiselier assert(f2.template target<TargetType>());
92b11df184SEric Fiselier assert(*f2.template target<TargetType>() == target);
93b11df184SEric Fiselier assert(f2.template target<FuncType*>() == 0);
94b11df184SEric Fiselier }
95b11df184SEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
96b11df184SEric Fiselier }
975a83710eSEric Fiselier
98b11df184SEric Fiselier template <class Alloc>
test_for_alloc(Alloc & alloc)99b11df184SEric Fiselier void test_for_alloc(Alloc& alloc) {
100b11df184SEric Fiselier test_FunctionObject<int()>(alloc);
101b11df184SEric Fiselier test_FunctionObject<int(int)>(alloc);
102b11df184SEric Fiselier test_FunctionObject<int(int, int)>(alloc);
103b11df184SEric Fiselier test_FunctionObject<int(int, int, int)>(alloc);
1045a83710eSEric Fiselier
105b11df184SEric Fiselier test_FreeFunction<int()>(alloc);
106b11df184SEric Fiselier test_FreeFunction<int(int)>(alloc);
107b11df184SEric Fiselier test_FreeFunction<int(int, int)>(alloc);
108b11df184SEric Fiselier test_FreeFunction<int(int, int, int)>(alloc);
1095a83710eSEric Fiselier
110b11df184SEric Fiselier test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
111b11df184SEric Fiselier test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
112b11df184SEric Fiselier test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
113b11df184SEric Fiselier }
1145a83710eSEric Fiselier
main(int,char **)1159a140a15SNikolas Klauser int main(int, char**) {
1160b43db52SDan Albert globalMemCounter.reset();
1175a83710eSEric Fiselier {
118b11df184SEric Fiselier bare_allocator<DummyClass> bare_alloc;
119b11df184SEric Fiselier test_for_alloc(bare_alloc);
1205a83710eSEric Fiselier }
1215a83710eSEric Fiselier {
1229a140a15SNikolas Klauser non_default_test_allocator<DummyClass> non_default_alloc(42, &alloc_stats);
123b11df184SEric Fiselier test_for_alloc(non_default_alloc);
12454519a6bSEric Fiselier }
125790df145SEric Fiselier #if TEST_STD_VER >= 11
126790df145SEric Fiselier {
127790df145SEric Fiselier using Fn = std::function<void(int, int, int)>;
128790df145SEric Fiselier static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, "");
129790df145SEric Fiselier static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, "");
130790df145SEric Fiselier static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, "");
131790df145SEric Fiselier static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, "");
132790df145SEric Fiselier }
133790df145SEric Fiselier #endif
134790df145SEric Fiselier
1352df59c50SJF Bastien
1362df59c50SJF Bastien return 0;
1375a83710eSEric Fiselier }
138