#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_LAZY_BASE_HPP #define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_LAZY_BASE_HPP #include "../container.hpp" #include "lazy_storage.hpp" namespace kgr { namespace detail { template struct LazyBase { private: using ref = typename std::remove_reference>::type&; using rref = typename std::remove_reference>::type&&; using ptr = decay_t>*; static constexpr bool nothrow_get() { return noexcept(std::declval().service()) && noexcept(std::declval>>().construct(std::declval>())); } public: ref get() noexcept(nothrow_get()) { if (!_service) { _service.construct(static_cast(this)->container().template service()); } return _service.value(); } ref operator*() & noexcept(nothrow_get()) { return get(); } ptr operator->() noexcept(nothrow_get()) { return &get(); } rref operator*() && noexcept(nothrow_get()) { return std::move(get()); } private: LazyStorage> _service; }; } // namespace detail } // namespace kgr #endif // KGR_KANGARU_INCLUDE_KANGARU_DETAIL_LAZY_BASE_HPP