aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/DI/concepts.hpp11
-rw-r--r--src/DI/container.cpp6
-rw-r--r--src/DI/container.hpp26
-rw-r--r--src/DI/container.tpp46
-rw-r--r--src/bootstrap.cpp6
6 files changed, 64 insertions, 32 deletions
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 <type_traits>
+
+template <typename Type>
+concept Function = is_func_v<Type>;
+
+template <typename Type>
+concept Abstract = std::is_abstract_v<Type>;
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<IGenericWrapper> &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 <concepts>
#include <memory>
-#include <type_traits>
#include <unordered_map>
class Container;
@@ -16,8 +17,8 @@ class BindingBuilder
public:
explicit BindingBuilder(Container *container) noexcept;
- template <class ObjectImpl,
- class = std::enable_if_t<std::is_base_of_v<Interface, ObjectImpl>>>
+ template <typename Impl>
+ requires std::derived_from<Impl, Interface>
void to() noexcept;
void to_factory(Interface func) noexcept;
@@ -31,17 +32,24 @@ class Container
public:
Container() noexcept = default;
+ template <typename Type>
+ using Ptr = std::shared_ptr<Type>;
+
template <class Interface>
auto bind() noexcept -> BindingBuilder<Interface>;
- template <class Interface, class = std::enable_if_t<std::is_abstract_v<Interface>>>
- auto get() const noexcept -> std::shared_ptr<Interface>;
+ template <class Interface>
+ requires Abstract<Interface>
+ auto get() const noexcept -> Ptr<Interface>;
- template <typename Interface, typename = std::enable_if_t<is_func_v<Interface>>>
+ template <typename Interface>
+ requires Function<Interface>
auto get() const noexcept -> Interface;
- std::unordered_map<BaseObjectType, std::shared_ptr<IGenericWrapper>, ObjectTypeHasher>
- bindings;
+ void add(BaseObjectType type, const Ptr<IGenericWrapper> &wrapper) noexcept;
+
+private:
+ std::unordered_map<BaseObjectType, Ptr<IGenericWrapper>, 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 <iostream>
-template <class Interface>
+template <typename Interface>
BindingBuilder<Interface>::BindingBuilder(Container *container) noexcept
: _container(container)
{
}
-template <class Interface>
-template <class ObjectImpl, class>
+template <typename Interface>
+template <typename Impl>
+requires std::derived_from<Impl, Interface>
void BindingBuilder<Interface>::to() noexcept
{
- _container->bindings.emplace(
- ObjectType<Interface>(),
- std::dynamic_pointer_cast<IGenericWrapper>(
- std::make_shared<ObjectWrapper<Interface, ObjectImpl>>(*_container)));
+ using Wrapper = ObjectWrapper<Interface, Impl>;
+
+ auto wrapper = Container::Ptr<Wrapper>(new Wrapper(*_container));
+
+ _container->add(ObjectType<Interface>(),
+ std::dynamic_pointer_cast<IGenericWrapper>(wrapper));
}
-template <class Interface>
+template <typename Interface>
void BindingBuilder<Interface>::to_factory(Interface func) noexcept
{
- _container->bindings.emplace(ObjectType<Interface>(),
- std::dynamic_pointer_cast<IGenericWrapper>(
- std::make_shared<FunctionWrapper<Interface>>(func)));
+ using Wrapper = FunctionWrapper<Interface>;
+
+ auto wrapper = Container::Ptr<Wrapper>(new Wrapper(func));
+
+ _container->add(ObjectType<Interface>(),
+ std::dynamic_pointer_cast<IGenericWrapper>(wrapper));
}
-template <class Interface>
+template <typename Interface>
auto Container::bind() noexcept -> BindingBuilder<Interface>
{
return BindingBuilder<Interface>(this);
}
-template <class Interface, class>
-auto Container::get() const noexcept -> std::shared_ptr<Interface>
+template <typename Interface>
+requires Abstract<Interface>
+auto Container::get() const noexcept -> Ptr<Interface>
{
ObjectType<Interface> 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<Interface>
exit(EXIT_FAILURE);
}
- auto wrapper = std::dynamic_pointer_cast<IWrapper<std::shared_ptr<Interface>>>(
- bindings.at(interface_type));
+ auto wrapper =
+ std::dynamic_pointer_cast<IWrapper<Ptr<Interface>>>(_bindings.at(interface_type));
return wrapper->get();
}
-template <typename Interface, typename>
+template <typename Interface>
+requires Function<Interface>
auto Container::get() const noexcept -> Interface
{
auto wrapper = std::dynamic_pointer_cast<IWrapper<Interface>>(
- bindings.at(ObjectType<Interface>()));
+ _bindings.at(ObjectType<Interface>()));
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 <concepts>
@@ -38,11 +39,8 @@
#include <random>
#include <string_view>
-template <typename Type>
-concept abstract = std::is_abstract_v<Type>;
-
template <typename Interface, typename Impl, typename... Params>
-requires abstract<Interface> && std::derived_from<Impl, Interface> &&
+requires Abstract<Interface> && std::derived_from<Impl, Interface> &&
std::constructible_from<Impl, Params...>
auto construct_as_interface(Params &&...parameters) -> std::shared_ptr<Interface>
{