From 1289268174a4a5aec2090a86de5c0c0ddc6d40ee Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Thu, 28 Jun 2012 13:42:55 +0200 Subject: [PATCH] Add SafeCountable and safe_ptr classes safe_ptr is a smart pointer which manage a safe count in pointed objects. SafeCountable provides the interface needed for safe_ptr and assert the safe count is zero in destructor. This permits to have pointers that guarantees their pointed object is alive. --- src/utils.hh | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/utils.hh b/src/utils.hh index e6d37cb8..ec2ac364 100644 --- a/src/utils.hh +++ b/src/utils.hh @@ -52,6 +52,63 @@ private: template T* Singleton::ms_instance = nullptr; +// *** safe_ptr: objects that assert nobody references them when they die *** + +typedef void* (*unspecified_bool_type)(); + +template +class safe_ptr +{ +public: + safe_ptr() : m_ptr(nullptr) {} + explicit safe_ptr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->inc_safe_count(); } + safe_ptr(const safe_ptr& other) : safe_ptr(other.m_ptr) {} + safe_ptr(safe_ptr&& other) : m_ptr(other.m_ptr) { other.m_ptr = nullptr; } + ~safe_ptr() { if (m_ptr) m_ptr->dec_safe_count(); } + + safe_ptr& operator=(const safe_ptr& other) + { + if (m_ptr != other.m_ptr) + { + if (m_ptr) + m_ptr->dec_safe_count(); + m_ptr = other.m_ptr; + if (m_ptr) + m_ptr->inc_safe_count(); + } + + return *this; + } + + bool operator== (const safe_ptr& other) const { return m_ptr == other.m_ptr; } + bool operator!= (const safe_ptr& other) const { return m_ptr != other.m_ptr; } + bool operator== (T* ptr) const { return m_ptr == ptr; } + bool operator!= (T* ptr) const { return m_ptr != ptr; } + + T& operator* () const { return *m_ptr; } + T* operator-> () const { return m_ptr; } + + T* get() const { return m_ptr; } + + operator unspecified_bool_type() const { return (unspecified_bool_type)(m_ptr); } + +private: + T* m_ptr; +}; + +class SafeCountable +{ +public: + SafeCountable() : m_count(0) {} + ~SafeCountable() { assert(m_count == 0); } + + void inc_safe_count() { ++m_count; } + void dec_safe_count() { --m_count; assert(m_count >= 0); } + +private: + int m_count; +}; + // *** Containers helpers *** template