aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-12-30 01:43:18 +0800
committercrupest <crupest@outlook.com>2023-12-30 01:43:18 +0800
commitf7a40005ec854131629acac8d03aed0e8a5da415 (patch)
tree6d8444c28ec8530f9d66d7779bc50f55df9dbf00
parente372810d67ae21dbc60aad71696290dad1c5e34a (diff)
downloadcru-f7a40005ec854131629acac8d03aed0e8a5da415.tar.gz
cru-f7a40005ec854131629acac8d03aed0e8a5da415.tar.bz2
cru-f7a40005ec854131629acac8d03aed0e8a5da415.zip
Refactor SelfResolvable.
-rw-r--r--include/cru/common/SelfResolvable.h39
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