#pragma once #include "pre_config.hpp" #include #include #include namespace cru { template class SelfResovable; template class ObjectResovler { friend SelfResovable; private: ObjectResovler(const std::shared_ptr& resolver) : resolver_(resolver) {} public: ObjectResovler(const ObjectResovler&) = default; ObjectResovler& operator=(const ObjectResovler&) = default; ObjectResovler(ObjectResovler&&) = default; ObjectResovler& operator=(ObjectResovler&&) = default; ~ObjectResovler() = 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 SelfResovable { public: SelfResovable() : resolver_(new T*(static_cast(this))) {} SelfResovable(const SelfResovable&) = delete; SelfResovable& operator=(const SelfResovable&) = delete; SelfResovable(SelfResovable&&) = delete; SelfResovable& operator=(SelfResovable&&) = delete; virtual ~SelfResovable() { (*resolver_) = nullptr; } ObjectResovler CreateResolver() { return ObjectResovler(resolver_); } private: std::shared_ptr resolver_; }; } // namespace cru