From 40c828455d094854d9e531fc7dd0d1a0244957b7 Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 29 Mar 2022 19:29:08 +0200 Subject: refactor: make container use concepts --- src/CMakeLists.txt | 1 + src/DI/concepts.hpp | 11 +++++++++++ src/DI/container.cpp | 6 ++++++ src/DI/container.hpp | 26 +++++++++++++++++--------- src/DI/container.tpp | 46 +++++++++++++++++++++++++++------------------- src/bootstrap.cpp | 6 ++---- 6 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 src/DI/concepts.hpp create mode 100644 src/DI/container.cpp (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4aa4a40..6daeadb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ file(GLOB SOURCES commands/move_cursor.cpp commands/quit.cpp commands/toggle_pause.cpp + DI/container.cpp DI/object_type.cpp) add_executable(${PROJECT_NAME} ${SOURCES}) diff --git a/src/DI/concepts.hpp b/src/DI/concepts.hpp new file mode 100644 index 0000000..12be546 --- /dev/null +++ b/src/DI/concepts.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "type_traits.hpp" + +#include + +template +concept Function = is_func_v; + +template +concept Abstract = std::is_abstract_v; diff --git a/src/DI/container.cpp b/src/DI/container.cpp new file mode 100644 index 0000000..4b86186 --- /dev/null +++ b/src/DI/container.cpp @@ -0,0 +1,6 @@ +#include "container.hpp" + +void Container::add(BaseObjectType type, const Ptr &wrapper) noexcept +{ + _bindings.insert({type, wrapper}); +} diff --git a/src/DI/container.hpp b/src/DI/container.hpp index 83f24ae..0c0155c 100644 --- a/src/DI/container.hpp +++ b/src/DI/container.hpp @@ -1,11 +1,12 @@ #pragma once #include "DI/interfaces/wrapper.hpp" + +#include "DI/concepts.hpp" #include "DI/object_type.hpp" -#include "DI/type_traits.hpp" +#include #include -#include #include class Container; @@ -16,8 +17,8 @@ class BindingBuilder public: explicit BindingBuilder(Container *container) noexcept; - template >> + template + requires std::derived_from void to() noexcept; void to_factory(Interface func) noexcept; @@ -31,17 +32,24 @@ class Container public: Container() noexcept = default; + template + using Ptr = std::shared_ptr; + template auto bind() noexcept -> BindingBuilder; - template >> - auto get() const noexcept -> std::shared_ptr; + template + requires Abstract + auto get() const noexcept -> Ptr; - template >> + template + requires Function auto get() const noexcept -> Interface; - std::unordered_map, ObjectTypeHasher> - bindings; + void add(BaseObjectType type, const Ptr &wrapper) noexcept; + +private: + std::unordered_map, ObjectTypeHasher> _bindings; }; #include "container.tpp" diff --git a/src/DI/container.tpp b/src/DI/container.tpp index 2573223..54b09c6 100644 --- a/src/DI/container.tpp +++ b/src/DI/container.tpp @@ -7,42 +7,49 @@ #include -template +template BindingBuilder::BindingBuilder(Container *container) noexcept : _container(container) { } -template -template +template +template +requires std::derived_from void BindingBuilder::to() noexcept { - _container->bindings.emplace( - ObjectType(), - std::dynamic_pointer_cast( - std::make_shared>(*_container))); + using Wrapper = ObjectWrapper; + + auto wrapper = Container::Ptr(new Wrapper(*_container)); + + _container->add(ObjectType(), + std::dynamic_pointer_cast(wrapper)); } -template +template void BindingBuilder::to_factory(Interface func) noexcept { - _container->bindings.emplace(ObjectType(), - std::dynamic_pointer_cast( - std::make_shared>(func))); + using Wrapper = FunctionWrapper; + + auto wrapper = Container::Ptr(new Wrapper(func)); + + _container->add(ObjectType(), + std::dynamic_pointer_cast(wrapper)); } -template +template auto Container::bind() noexcept -> BindingBuilder { return BindingBuilder(this); } -template -auto Container::get() const noexcept -> std::shared_ptr +template +requires Abstract +auto Container::get() const noexcept -> Ptr { ObjectType interface_type; - if (bindings.count(interface_type) == 0) + if (_bindings.count(interface_type) == 0) { std::cerr << "Error: Tried to get a item from the container using unbound interface '" @@ -50,17 +57,18 @@ auto Container::get() const noexcept -> std::shared_ptr exit(EXIT_FAILURE); } - auto wrapper = std::dynamic_pointer_cast>>( - bindings.at(interface_type)); + auto wrapper = + std::dynamic_pointer_cast>>(_bindings.at(interface_type)); return wrapper->get(); } -template +template +requires Function auto Container::get() const noexcept -> Interface { auto wrapper = std::dynamic_pointer_cast>( - bindings.at(ObjectType())); + _bindings.at(ObjectType())); return wrapper->get(); } diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp index 1436301..f22c689 100644 --- a/src/bootstrap.cpp +++ b/src/bootstrap.cpp @@ -31,6 +31,7 @@ #include "randomization/generator.hpp" #include "randomization/seed_generator.hpp" +#include "DI/concepts.hpp" #include "util/function.hpp" #include @@ -38,11 +39,8 @@ #include #include -template -concept abstract = std::is_abstract_v; - template -requires abstract && std::derived_from && +requires Abstract && std::derived_from && std::constructible_from auto construct_as_interface(Params &&...parameters) -> std::shared_ptr { -- cgit v1.2.3-18-g5258