aboutsummaryrefslogtreecommitdiff
path: root/src/DI/value_functor.hpp
blob: 1553af9b0615e716ff35689bf717a6222adf2f72 (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
#pragma once

#include "DI/interfaces/copyable_functor.hpp"

#include "DI/copyable_functor.hpp"
#include "DI/extra_concepts.hpp"

#include <memory>
#include <type_traits>

/**
 * Creates a value-type from a copyable functor.
 */
template <class Function>
class ValueFunctor;

template <class Return, class... Args>
class ValueFunctor<Return(Args...)>
{
	using TargetFunctor = ICopyableFunctor<Return(Args...)>;

public:
	ValueFunctor() noexcept;

	template <class Function>
	requires NotSameAs<std::decay_t<Function>, ValueFunctor>
	// NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
	explicit ValueFunctor(Function &&function)
		: ValueFunctor(std::forward<Function>(function), std::allocator<Function>())
	{
	}

	template <class Function, class Allocator>
	ValueFunctor(Function &&function, const Allocator &allocator);

	ValueFunctor(const ValueFunctor &val_functor);

	ValueFunctor(ValueFunctor &&val_functor) noexcept;

	~ValueFunctor();

	auto operator=(const ValueFunctor &val_functor) noexcept = delete;

	auto operator=(ValueFunctor &&val_functor) noexcept -> ValueFunctor &;

	auto operator=(std::nullptr_t) -> ValueFunctor &;

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

	explicit operator bool() const noexcept;

	[[nodiscard]] auto target_type() const noexcept -> const std::type_info &;

	template <typename Target>
	auto target() const noexcept -> const Target *;

private:
	typename std::aligned_storage<3 * sizeof(void *)>::type _buf{};

	TargetFunctor *_functor;

	static auto _as_copyable_functor(void *function_ptr) -> TargetFunctor *;
};

#include "value_functor.tpp"