aboutsummaryrefslogtreecommitdiff
path: root/src/DI/alloc_functor.hpp
blob: ea40b22ee71c57b12fb84148836648c43daeb042 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#pragma once

#include "DI/allocation.hpp"
#include "DI/compressed_pair.hpp"

#include <memory>
#include <type_traits>
#include <utility>

template <typename Return>
struct InvokeReturnWrapper
{
	template <typename... Args>
	static auto call(Args &&...args) -> Return;
};

/**
 * Holds a functor and a allocator.
 */
template <class Function, class Allocator, class FunctionSignature>
class AllocFunctor;

template <class Function, class Allocator, class Return, class... Args>
class AllocFunctor<Function, Allocator, Return(Args...)>
{
public:
	using Target = Function;
	using Alloc = Allocator;

	explicit AllocFunctor(Target &&function);

	explicit AllocFunctor(const Target &function, const Alloc &allocator);

	explicit AllocFunctor(const Target &function, Alloc &&allocator);

	explicit AllocFunctor(Target &&function, Alloc &&allocator);

	auto operator()(Args &&...args) -> Return;

	[[nodiscard]] auto target() const -> const Target &;

	[[nodiscard]] auto get_allocator() const -> const Alloc &;

	[[nodiscard]] auto clone() const -> AllocFunctor *;

	void destroy() noexcept;

	static void destroy_and_delete(AllocFunctor *functor);

private:
	CompressedPair<Function, Allocator> _function;
};

/**
 * Holds a functor and a allocator.
 */
template <class Function, class FB>
class DefaultAllocFunctor;

template <class Function, class Return, class... Args>
class DefaultAllocFunctor<Function, Return(Args...)>
{
public:
	using Target = Function;

	explicit DefaultAllocFunctor(Target &&function);

	explicit DefaultAllocFunctor(const Target &function);

	auto operator()(Args &&...args) -> Return;

	auto target() const -> const Target &;

	auto clone() const -> DefaultAllocFunctor *;

	void destroy() noexcept;

	static void destroy_and_delete(DefaultAllocFunctor *function);

private:
	Function _function;
};

#include "alloc_functor.tpp"