From 148bfcc2c0d6627b259d29bf1690bbbb21d6b366 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sat, 8 Oct 2016 17:23:27 -0400 Subject: [PATCH] Reduce the size of ref to a single pointer. Rather than tracking |T*|, |OwnedPtrDeleter|, and a |bool|; ref now just holds an |owned*|. It uses uintptr_t's max value as a deletion sentinel rather than a separate flag. And with the actual owned*, the deleter doesn't need to be held separately either. --- zcpointer.h | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/zcpointer.h b/zcpointer.h index bf86fb5..c4b8991 100644 --- a/zcpointer.h +++ b/zcpointer.h @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include @@ -86,10 +87,10 @@ class owned : public std::unique_ptr> { template class ref { public: - ref() : ptr_(nullptr), deleter_(nullptr), deleted_(true) {} + ref() : ptr_(DeletedSentinel()) {} - explicit ref(owned& o) : ptr_(o.GetRawPointer()), deleter_(&o.get_deleter()) { - deleter_->AddRef(this); + explicit ref(owned& o) : ptr_(&o) { + ptr_->get_deleter().AddRef(this); } ref(const ref& o) { @@ -98,41 +99,45 @@ class ref { ref& operator=(const ref& o) { ptr_ = o.ptr_; - deleter_ = o.deleter_; - deleted_ = o.deleted_; - if (!deleted_) { - deleter_->AddRef(this); + if (!IsDeleted()) { + ptr_->get_deleter().AddRef(this); } return *this; } ~ref() { + ptr_->get_deleter().RemoveRef(this); MarkDeleted(); - deleter_->RemoveRef(this); } T* operator->() const { CheckDeleted(); - return ptr_; + return ptr_->GetRawPointer(); } protected: friend class internal::OwnedPtrDeleter; void MarkDeleted() { - deleted_ = true; + ptr_ = DeletedSentinel(); } private: void CheckDeleted() const { - if (deleted_) { + if (IsDeleted()) { internal::RaiseUseAfterFree("attempt to access deleted pointer"); } } - T* ptr_; - internal::OwnedPtrDeleter* deleter_; - bool deleted_ = false; + bool IsDeleted() const { + return ptr_ == DeletedSentinel(); + } + + inline static owned* DeletedSentinel() { + return reinterpret_cast*>(std::numeric_limits::max()); + } + + owned* ptr_; }; #else -- 2.22.5