diff options
Diffstat (limited to 'include/cru')
| -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  | 
