#pragma once #include "pre_config.hpp" #include #include #include namespace cru { template class SelfResolvable; template class ObjectResolver { friend SelfResolvable; private: ObjectResolver(const std::shared_ptr& resolver) : resolver_(resolver) {} public: ObjectResolver(const ObjectResolver&) = default; ObjectResolver& operator=(const ObjectResolver&) = default; ObjectResolver(ObjectResolver&&) = default; ObjectResolver& operator=(ObjectResolver&&) = default; ~ObjectResolver() = default; T* Resolve() const { // resolver_ is null only when this has been moved. // You shouldn't resolve a moved resolver. So assert it. assert(resolver_); return *resolver_; } private: std::shared_ptr resolver_; }; template class SelfResolvable { public: SelfResolvable() : resolver_(new T*(static_cast(this))) {} SelfResolvable(const SelfResolvable&) = delete; SelfResolvable& operator=(const SelfResolvable&) = delete; SelfResolvable(SelfResolvable&&) = delete; SelfResolvable& operator=(SelfResolvable&&) = delete; virtual ~SelfResolvable() { (*resolver_) = nullptr; } ObjectResolver CreateResolver() { return ObjectResolver(resolver_); } private: std::shared_ptr resolver_; }; } // namespace cru