aboutsummaryrefslogtreecommitdiff
path: root/include/cru/base/SelfResolvable.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/base/SelfResolvable.h')
-rw-r--r--include/cru/base/SelfResolvable.h125
1 files changed, 39 insertions, 86 deletions
diff --git a/include/cru/base/SelfResolvable.h b/include/cru/base/SelfResolvable.h
index 84fa54f6..308de486 100644
--- a/include/cru/base/SelfResolvable.h
+++ b/include/cru/base/SelfResolvable.h
@@ -1,7 +1,7 @@
#pragma once
+#include "Base.h"
#include <cassert>
-#include <functional>
#include <memory>
#include <type_traits>
@@ -16,70 +16,51 @@ class ObjectResolver {
friend class ObjectResolver;
private:
- template <typename U>
- using Accessor_ = std::function<U*(const std::shared_ptr<void*>&)>;
- using ThisAccessor_ = Accessor_<T>;
+ explicit ObjectResolver(std::shared_ptr<bool> destroyed, T* ptr)
+ : destroyed_(std::move(destroyed)), ptr_(ptr) {}
- explicit ObjectResolver(T* o)
- : shared_object_ptr_(new void*(o)),
- accessor_([](const std::shared_ptr<void*>& ptr) {
- return static_cast<T*>(*ptr);
- }) {}
- explicit ObjectResolver(std::shared_ptr<void*> ptr, ThisAccessor_ accessor)
- : shared_object_ptr_(std::move(ptr)), accessor_(std::move(accessor)) {}
+ public:
+ CRU_DEFAULT_COPY(ObjectResolver)
+ CRU_DEFAULT_MOVE(ObjectResolver)
template <typename U>
- static ThisAccessor_ CreateAccessor(Accessor_<U> parent_accessor) {
- return [parent_accessor =
- std::move(parent_accessor)](const std::shared_ptr<void*>& ptr) {
- return static_cast<T*>(parent_accessor(ptr));
- };
- }
-
- public:
- template <typename U,
- typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
ObjectResolver(const ObjectResolver<U>& other)
- : shared_object_ptr_(other.shared_object_ptr_),
- accessor_(CreateAccessor(other.accessor_)) {}
+ requires(std::is_convertible_v<U*, T*>)
+ : destroyed_(other.destroyed_), ptr_(static_cast<T*>(other.ptr_)) {}
- template <typename U,
- typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
+ template <typename U>
ObjectResolver(ObjectResolver<U>&& other)
- : shared_object_ptr_(std::move(other.shared_object_ptr_)),
- accessor_(CreateAccessor(std::move(other.accessor_))) {}
-
- ObjectResolver(const ObjectResolver&) = default;
- ObjectResolver& operator=(const ObjectResolver&) = default;
- ObjectResolver(ObjectResolver&&) = default;
- ObjectResolver& operator=(ObjectResolver&&) = default;
- ~ObjectResolver() = default;
-
- template <typename U,
- typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
- ObjectResolver& operator=(const ObjectResolver<U>& other) {
+ requires(std::is_convertible_v<U*, T*>)
+ : destroyed_(std::move(other.destroyed_)),
+ ptr_(static_cast<T*>(other.ptr_)) {}
+
+ template <typename U>
+ ObjectResolver& operator=(const ObjectResolver<U>& other)
+ requires(std::is_convertible_v<U*, T*>)
+ {
if (this != &other) {
- this->shared_object_ptr_ = other.shared_object_ptr_;
- this->accessor_ = CreateAccessor(other.accessor_);
+ this->destroyed_ = other.destroyed_;
+ this->ptr_ = static_cast<T*>(other.ptr_);
}
return *this;
}
- template <typename U,
- typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
- ObjectResolver& operator=(ObjectResolver<U>&& other) {
+ template <typename U>
+ ObjectResolver& operator=(ObjectResolver<U>&& other)
+ requires(std::is_convertible_v<U*, T*>)
+ {
if (this != &other) {
- this->shared_object_ptr_ = std::move(other.shared_object_ptr_);
- this->accessor_ = CreateAccessor(std::move(other.shared_object_ptr_));
+ this->destroyed_ = std::move(other.destroyed_);
+ this->ptr_ = static_cast<T*>(other.ptr_);
}
return *this;
}
- bool IsValid() const { return this->shared_object_ptr_ != nullptr; }
+ bool IsValid() const { return this->destroyed_ != nullptr; }
T* Resolve() const {
assert(IsValid());
- return this->accessor_(this->shared_object_ptr_);
+ return *destroyed_ ? nullptr : ptr_;
}
/**
@@ -87,21 +68,16 @@ class ObjectResolver {
*/
T* operator()() const { return Resolve(); }
- template <typename U,
- typename = std::enable_if_t<std::is_convertible_v<T*, U*>>>
- operator ObjectResolver<U>() const {
+ template <typename U>
+ operator ObjectResolver<U>() const
+ requires(std::is_convertible_v<T*, U*>)
+ {
return ObjectResolver<U>(*this);
}
private:
- void SetResolvedObject(T* o) {
- assert(IsValid());
- *this->shared_object_ptr_ = o;
- }
-
- private:
- std::shared_ptr<void*> shared_object_ptr_;
- std::function<T*(const std::shared_ptr<void*>&)> accessor_;
+ std::shared_ptr<bool> destroyed_;
+ T* ptr_;
};
/**
@@ -116,38 +92,15 @@ class ObjectResolver {
template <typename T>
class SelfResolvable {
public:
- SelfResolvable() : resolver_(CastToSubClass()) {}
- 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_)) {
- this->resolver_.SetResolvedObject(CastToSubClass());
- }
-
- // Old resolvers for this object will resolve to nullptr.
- // Other's resolvers will now resolve to this.
- SelfResolvable& operator=(SelfResolvable&& other) {
- if (this != &other) {
- this->resolver_ = std::move(other.resolver_);
- this->resolver_.SetResolvedObject(CastToSubClass());
- }
- return *this;
- }
+ SelfResolvable() : destroyed_(new bool(false)) {}
+ CRU_DELETE_COPY(SelfResolvable)
+ virtual ~SelfResolvable() { *destroyed_ = true; }
- virtual ~SelfResolvable() {
- if (this->resolver_.IsValid()) {
- this->resolver_.SetResolvedObject(nullptr);
- }
+ ObjectResolver<T> CreateResolver() {
+ return ObjectResolver<T>(destroyed_, static_cast<T*>(this));
}
- ObjectResolver<T> CreateResolver() { return resolver_; }
-
- private:
- T* CastToSubClass() { return static_cast<T*>(this); }
-
private:
- ObjectResolver<T> resolver_;
+ std::shared_ptr<bool> destroyed_;
};
} // namespace cru