From b36d072ad7a7b9c6e30fcb25d6bbb001a8393468 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 10 Apr 2022 17:20:49 +0200 Subject: refactor: add factory class & make DI container return unique ptrs --- src/DI/factory.hpp | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/DI/factory.hpp (limited to 'src/DI/factory.hpp') diff --git a/src/DI/factory.hpp b/src/DI/factory.hpp new file mode 100644 index 0000000..13d0eb5 --- /dev/null +++ b/src/DI/factory.hpp @@ -0,0 +1,189 @@ +#pragma once + +#include "DI/interfaces/copyable_functor.hpp" + +#include "DI/alloc_functor.hpp" +#include "DI/allocation.hpp" +#include "DI/copyable_functor.hpp" +#include "DI/extra_concepts.hpp" +#include "DI/strip_signature.hpp" +#include "DI/value_functor.hpp" + +#include +#include + +template +class Factory; + +template +// NOLINTNEXTLINE(readability-identifier-naming) +struct maybe_derive_from_unary_function +{ +}; + +template +struct maybe_derive_from_unary_function + : public std::unary_function +{ +}; + +template +// NOLINTNEXTLINE(readability-identifier-naming) +struct maybe_derive_from_binary_function +{ +}; + +template +struct maybe_derive_from_binary_function + : public std::binary_function +{ +}; + +template +auto not_null(Function const & /*unused*/) -> bool +{ + return true; +} + +template +auto not_null(Function *function_ptr) -> bool +{ + return function_ptr; +} + +template +auto not_null(Return Class::*method_ptr) -> bool +{ + return method_ptr; +} + +template +auto not_null(Factory const &factory) -> bool +{ + return !!factory; +} + +template +// NOLINTNEXTLINE(readability-identifier-naming) +struct uncvref +{ + using type = + typename std::remove_cv::type>::type; +}; + +template +// NOLINTNEXTLINE(readability-identifier-naming) +using uncvref_t = typename uncvref::type; + +template +// NOLINTNEXTLINE(readability-identifier-naming) +struct is_core_convertible : public std::false_type +{ +}; + +template +struct is_core_convertible< + Tp, Up, decltype(static_cast(0)(static_cast(0)()))> + : public std::true_type +{ +}; + +template +constexpr bool is_core_convertible_v = is_core_convertible::value; + +template +concept Callable = !std::is_same_v, Factory> && + std::is_invocable_v && + is_core_convertible_v, Return>; + +template +class Factory : public maybe_derive_from_unary_function, + public maybe_derive_from_binary_function +{ +public: + using Result = Return; + + Factory() noexcept = default; + + explicit Factory(std::nullptr_t) noexcept {} + + Factory(const Factory &factory); + + Factory(Factory &&factory) noexcept; + + template + requires Callable + // NOLINTNEXTLINE(google-explicit-constructor) + Factory(Function function) : _functor(std::move(function)) + { + } + + auto operator=(const Factory &factory) = delete; + + auto operator=(Factory &&factory) noexcept -> Factory &; + + auto operator=(std::nullptr_t) noexcept -> Factory &; + + ~Factory(); + + explicit operator bool() const noexcept; + + // deleted overloads close possible hole in the type system + template + auto operator==(const Factory &) const -> bool = delete; + + template + auto operator!=(const Factory &) const -> bool = delete; + + auto operator()(Args... args) const -> Return; + + [[nodiscard]] auto target_type() const noexcept -> const std::type_info &; + + template + auto target() noexcept -> Tp *; + + template + auto target() const noexcept -> const Tp *; + +private: + using ValFunctor = ValueFunctor; + + ValFunctor _functor; +}; + +template +Factory(Return (*)(Args...)) -> Factory; + +template > +Factory(Function) -> Factory; + +template +inline auto operator==(const Factory &factory, std::nullptr_t) noexcept + -> bool +{ + return !factory; +} + +template +inline auto operator==(std::nullptr_t, const Factory &factory) noexcept + -> bool +{ + return !factory; +} + +template +inline auto operator!=(const Factory &factory, std::nullptr_t) noexcept + -> bool +{ + return static_cast(factory); +} + +template +inline auto operator!=(std::nullptr_t, const Factory &factory) noexcept + -> bool +{ + return static_cast(factory); +} + +#include "factory.tpp" -- cgit v1.2.3-18-g5258