From 8673907e4e3f2f9ff6e8bd18aaf3ddc6d84c0e64 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 1 Jan 2024 22:20:21 +0800 Subject: NEED TEST: add support for pointer conversion in ObjectResolver. --- include/cru/common/SelfResolvable.h | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) (limited to 'include/cru/common/SelfResolvable.h') diff --git a/include/cru/common/SelfResolvable.h b/include/cru/common/SelfResolvable.h index ce5b1628..84fa54f6 100644 --- a/include/cru/common/SelfResolvable.h +++ b/include/cru/common/SelfResolvable.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include namespace cru { template @@ -10,22 +12,74 @@ class SelfResolvable; template class ObjectResolver { friend SelfResolvable; + template + friend class ObjectResolver; private: - explicit ObjectResolver(T* o) : shared_object_ptr_(new T*(o)) {} + template + using Accessor_ = std::function&)>; + using ThisAccessor_ = Accessor_; + + explicit ObjectResolver(T* o) + : shared_object_ptr_(new void*(o)), + accessor_([](const std::shared_ptr& ptr) { + return static_cast(*ptr); + }) {} + explicit ObjectResolver(std::shared_ptr ptr, ThisAccessor_ accessor) + : shared_object_ptr_(std::move(ptr)), accessor_(std::move(accessor)) {} + + template + static ThisAccessor_ CreateAccessor(Accessor_ parent_accessor) { + return [parent_accessor = + std::move(parent_accessor)](const std::shared_ptr& ptr) { + return static_cast(parent_accessor(ptr)); + }; + } public: + template >> + ObjectResolver(const ObjectResolver& other) + : shared_object_ptr_(other.shared_object_ptr_), + accessor_(CreateAccessor(other.accessor_)) {} + + template >> + ObjectResolver(ObjectResolver&& 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 >> + ObjectResolver& operator=(const ObjectResolver& other) { + if (this != &other) { + this->shared_object_ptr_ = other.shared_object_ptr_; + this->accessor_ = CreateAccessor(other.accessor_); + } + return *this; + } + + template >> + ObjectResolver& operator=(ObjectResolver&& other) { + if (this != &other) { + this->shared_object_ptr_ = std::move(other.shared_object_ptr_); + this->accessor_ = CreateAccessor(std::move(other.shared_object_ptr_)); + } + return *this; + } + bool IsValid() const { return this->shared_object_ptr_ != nullptr; } T* Resolve() const { assert(IsValid()); - return *this->shared_object_ptr_; + return this->accessor_(this->shared_object_ptr_); } /** @@ -33,6 +87,12 @@ class ObjectResolver { */ T* operator()() const { return Resolve(); } + template >> + operator ObjectResolver() const { + return ObjectResolver(*this); + } + private: void SetResolvedObject(T* o) { assert(IsValid()); @@ -40,7 +100,8 @@ class ObjectResolver { } private: - std::shared_ptr shared_object_ptr_; + std::shared_ptr shared_object_ptr_; + std::function&)> accessor_; }; /** -- cgit v1.2.3