#pragma once #include "container.hpp" #include "function_wrapper.hpp" #include "object_wrapper.hpp" #include template BindingBuilder::BindingBuilder(Container *container) noexcept : _container(container) { } template template requires Abstract && std::derived_from void BindingBuilder::to() noexcept { using Wrapper = ObjectWrapper; auto wrapper = Container::WrapperPtr(new Wrapper(*_container)); _container->add( ObjectType(), std::dynamic_pointer_cast(wrapper) ); } template template requires IsFactory && std::constructible_from void BindingBuilder::to_factory(FactoryFunc factory) noexcept { using Wrapper = FunctionWrapper; auto wrapper = Container::WrapperPtr(new Wrapper(factory)); _container->add( ObjectType(), std::dynamic_pointer_cast(wrapper) ); } template auto Container::bind() noexcept -> BindingBuilder { return BindingBuilder(this); } template requires Abstract auto Container::get() const noexcept -> std::unique_ptr { ObjectType interface_type; if (_bindings.count(interface_type) == 0) { std::cerr << "Error: Tried to get a item from the container using unbound interface '" << interface_type.name() << "'" << std::endl; exit(EXIT_FAILURE); } auto wrapper = std::dynamic_pointer_cast>>( _bindings.at(interface_type) ); return wrapper->get(); } template requires IsFactory auto Container::get() const noexcept -> AFactory { auto wrapper = std::dynamic_pointer_cast>(_bindings.at(ObjectType()) ); return wrapper->get(); }