diff options
Diffstat (limited to 'src/DI/value_functor.hpp')
-rw-r--r-- | src/DI/value_functor.hpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/DI/value_functor.hpp b/src/DI/value_functor.hpp new file mode 100644 index 0000000..1553af9 --- /dev/null +++ b/src/DI/value_functor.hpp @@ -0,0 +1,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" |