Files
cpp-thirdparty/noarch/include/kangaru/operator.hpp
Bassem Girgis 81b4b9e273 Initial commit
2018-12-20 17:34:07 -06:00

147 lines
3.7 KiB
C++

#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<typename CRTP, template<typename> class Map>
struct InvokerBase {
template<typename F, typename... Args, enable_if_t<is_invoke_valid<Map, decay_t<F>, Args...>::value, int> = 0>
invoke_function_result_t<Map, decay_t<F>, Args...> operator()(F&& f, Args&&... args) {
return static_cast<CRTP*>(this)->container().template invoke<Map>(std::forward<F>(f), std::forward<Args>(args)...);
}
Sink operator()(detail::NotInvokableError = {}, ...) = delete;
};
template<typename CRTP, typename T>
struct GeneratorBase {
static_assert(!is_single<T>::value, "Generator only work with non-single services.");
template<typename... Args, enable_if_t<is_service_valid<T, Args...>::value, int> = 0>
ServiceType<T> operator()(Args&&... args) {
return static_cast<CRTP*>(this)->container().template service<T>(std::forward<Args>(args)...);
}
template<typename U = T, enable_if_t<std::is_default_constructible<ServiceError<U>>::value, int> = 0>
Sink operator()(ServiceError<U> = {}) = delete;
template<typename... Args>
Sink operator()(ServiceError<T, identity_t<Args>...>, Args&&...) = delete;
};
} // namespace detail
template<template<typename> class Map>
struct Invoker : detail::InvokerBase<Invoker<Map>, Map> {
explicit Invoker(Container& container) : _container{&container} {}
private:
kgr::Container& container() {
return *_container;
}
const kgr::Container& container() const {
return *_container;
}
friend struct detail::InvokerBase<Invoker<Map>, Map>;
kgr::Container* _container;
};
using DefaultInvoker = Invoker<kgr::AdlMap>;
template<template<typename> class Map>
struct ForkedInvoker : detail::InvokerBase<ForkedInvoker<Map>, 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<ForkedInvoker<Map>, Map>;
kgr::Container _container;
};
using DefaultForkedInvoker = ForkedInvoker<kgr::AdlMap>;
template<typename T>
struct Generator : detail::GeneratorBase<Generator<T>, T> {
explicit Generator(Container& container) : _container{&container} {}
private:
kgr::Container& container() {
return *_container;
}
const kgr::Container& container() const {
return *_container;
}
friend struct detail::GeneratorBase<Generator<T>, T>;
kgr::Container* _container;
};
template<typename T>
struct ForkedGenerator : detail::GeneratorBase<ForkedGenerator<T>, 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<ForkedGenerator<T>, T>;
kgr::Container _container;
};
template<typename T>
struct Lazy : detail::LazyBase<Lazy<T>, 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<Lazy<T>, T>;
kgr::Container* _container;
};
template<typename T>
struct ForkedLazy : detail::LazyBase<ForkedLazy<T>, 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<ForkedLazy<T>, T>;
kgr::Container _container;
};
} // namespace kgr
#endif // KGR_KANGARU_INCLUDE_KANGARU_OPERATOR_HPP