diff options
Diffstat (limited to 'include/cru/common/SelfResolvable.h')
-rw-r--r-- | include/cru/common/SelfResolvable.h | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/include/cru/common/SelfResolvable.h b/include/cru/common/SelfResolvable.h index 0cbb35fb..5a609340 100644 --- a/include/cru/common/SelfResolvable.h +++ b/include/cru/common/SelfResolvable.h @@ -1,6 +1,6 @@ #pragma once -#include "PreConfig.h" +#include <cassert> #include <memory> namespace cru { @@ -12,7 +12,7 @@ class ObjectResolver { friend SelfResolvable<T>; private: - ObjectResolver(const std::shared_ptr<T*>& resolver) : resolver_(resolver) {} + explicit ObjectResolver(T* o) : shared_object_ptr_(new T*(o)) {} public: ObjectResolver(const ObjectResolver&) = default; @@ -21,48 +21,57 @@ class ObjectResolver { ObjectResolver& operator=(ObjectResolver&&) = default; ~ObjectResolver() = default; + bool IsValid() const { return this->shared_object_ptr_ != nullptr; } + T* Resolve() const { - // resolver_ is null only when this has been moved. - // You shouldn't resolve a moved resolver. So assert it. - Expects(resolver_); - return *resolver_; + assert(IsValid()); + return *this->shared_object_ptr_; + } + + explicit operator bool() const { return this->IsValid(); } + + private: + void SetResolvedObject(T* o) { + assert(IsValid()); + *this->shared_object_ptr_ = o; } private: - std::shared_ptr<T*> resolver_; + std::shared_ptr<T*> shared_object_ptr_; }; template <typename T> class SelfResolvable { public: - SelfResolvable() : resolver_(new T*(static_cast<T*>(this))) {} + SelfResolvable() : resolver_(static_cast<T*>(this)) {} SelfResolvable(const SelfResolvable&) = delete; SelfResolvable& operator=(const SelfResolvable&) = delete; // Resolvers to old object will resolve to new object. SelfResolvable(SelfResolvable&& other) : resolver_(std::move(other.resolver_)) { - (*resolver_) = static_cast<T*>(this); + this->resolver_.SetResolvedObject(this); } // Old resolvers for this object will resolve to nullptr. // Other's resolvers will now resolve to this. SelfResolvable& operator=(SelfResolvable&& other) { if (this != &other) { - (*resolver_) = nullptr; - resolver_ = std::move(other.resolver_); - (*resolver_) = static_cast<T*>(this); + this->resolver_ = std::move(other.resolver_); + this->resolver_.SetResolvedObject(this); } return *this; } virtual ~SelfResolvable() { - if (resolver_ != nullptr) (*resolver_) = nullptr; + if (this->resolver_.IsValid()) { + this->resolver_.SetResolvedObject(nullptr); + } } - ObjectResolver<T> CreateResolver() { return ObjectResolver<T>(resolver_); } + ObjectResolver<T> CreateResolver() { return resolver_; } private: - std::shared_ptr<T*> resolver_; + ObjectResolver<T> resolver_; }; } // namespace cru |