#ifndef KGR_KANGARU_INCLUDE_KANGARU_OPERATOR_HPP #define KGR_KANGARU_INCLUDE_KANGARU_OPERATOR_HPP #include "container.hpp" #include "detail/lazy_base.hpp" namespace kgr { namespace detail { template class Map> struct InvokerBase { template, Args...>::value, int> = 0> invoke_function_result_t, Args...> operator()(F&& f, Args&&... args) { return static_cast(this)->container().template invoke(std::forward(f), std::forward(args)...); } Sink operator()(detail::NotInvokableError = {}, ...) = delete; }; template struct GeneratorBase { static_assert(!is_single::value, "Generator only work with non-single services."); template::value, int> = 0> ServiceType operator()(Args&&... args) { return static_cast(this)->container().template service(std::forward(args)...); } template>::value, int> = 0> Sink operator()(ServiceError = {}) = delete; template Sink operator()(ServiceError...>, Args&&...) = delete; }; } // namespace detail template class Map> struct Invoker : detail::InvokerBase, Map> { explicit Invoker(Container& container) : _container{&container} {} private: kgr::Container& container() { return *_container; } const kgr::Container& container() const { return *_container; } friend struct detail::InvokerBase, Map>; kgr::Container* _container; }; using DefaultInvoker = Invoker; template class Map> struct ForkedInvoker : detail::InvokerBase, Map> { explicit ForkedInvoker(Container container) : _container{std::move(container)} {} private: kgr::Container& container() { return _container; } const kgr::Container& container() const { return _container; } friend struct detail::InvokerBase, Map>; kgr::Container _container; }; using DefaultForkedInvoker = ForkedInvoker; template struct Generator : detail::GeneratorBase, T> { explicit Generator(Container& container) : _container{&container} {} private: kgr::Container& container() { return *_container; } const kgr::Container& container() const { return *_container; } friend struct detail::GeneratorBase, T>; kgr::Container* _container; }; template struct ForkedGenerator : detail::GeneratorBase, T> { explicit ForkedGenerator(Container container) : _container{std::move(container)} {} private: kgr::Container& container() { return _container; } const kgr::Container& container() const { return _container; } friend struct detail::GeneratorBase, T>; kgr::Container _container; }; template struct Lazy : detail::LazyBase, T> { explicit Lazy(kgr::Container& container) : _container{&container} {} private: kgr::Container& container() { return *_container; } const kgr::Container& container() const { return *_container; } friend struct detail::LazyBase, T>; kgr::Container* _container; }; template struct ForkedLazy : detail::LazyBase, T> { explicit ForkedLazy(kgr::Container container) : _container{std::move(container)} {} private: kgr::Container& container() { return _container; } const kgr::Container& container() const { return _container; } friend struct detail::LazyBase, T>; kgr::Container _container; }; } // namespace kgr #endif // KGR_KANGARU_INCLUDE_KANGARU_OPERATOR_HPP