From f7a40005ec854131629acac8d03aed0e8a5da415 Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 30 Dec 2023 01:43:18 +0800 Subject: Refactor SelfResolvable. --- include/cru/common/SelfResolvable.h | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'include/cru') 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 #include namespace cru { @@ -12,7 +12,7 @@ class ObjectResolver { friend SelfResolvable; private: - ObjectResolver(const std::shared_ptr& 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 resolver_; + std::shared_ptr shared_object_ptr_; }; template class SelfResolvable { public: - SelfResolvable() : resolver_(new T*(static_cast(this))) {} + SelfResolvable() : resolver_(static_cast(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(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(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 CreateResolver() { return ObjectResolver(resolver_); } + ObjectResolver CreateResolver() { return resolver_; } private: - std::shared_ptr resolver_; + ObjectResolver resolver_; }; } // namespace cru -- cgit v1.2.3