From 98063cdbef447e6a7fe6a253bd76c66d4529d585 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 18 Jul 2016 02:03:32 +0200 Subject: [PATCH] [DEV] continue integrate void sharedPtr --- ememory/SharedPtr.h | 78 ++++++++++++++++------------- ememory/WeakPtr.h | 10 ++++ ememory/details/SharedPtr.hxx | 94 +++++++++++++++++++++++++++++++---- ememory/details/WeakPtr.hxx | 46 ++++++++++++++++- 4 files changed, 182 insertions(+), 46 deletions(-) diff --git a/ememory/SharedPtr.h b/ememory/SharedPtr.h index 7138e5d..5419e1a 100644 --- a/ememory/SharedPtr.h +++ b/ememory/SharedPtr.h @@ -18,9 +18,26 @@ namespace ememory { template class SharedPtr { friend class WeakPtr; + public: + using deleterCall = std::function; private: EMEMORY_TYPE* m_element; ememory::Counter* m_counter; + deleterCall m_deleter; + template::value + && std::is_integral::value + , int>::type = 0> + deleterCall createDeleter(EMEMORY_TYPE2) const { + return [](EMEMORY_TYPE* _data) { delete(_data);}; + } + template::value + && std::is_integral::value + , int>::type = 0> + deleterCall createDeleter(EMEMORY_TYPE2) const { + return [](EMEMORY_TYPE* _data) { EMEMORY_ERROR("Request deleter of a void type ==> surrely an error");}; + } public: template::value @@ -41,6 +58,16 @@ namespace ememory { SharedPtr& operator= (const SharedPtr& _obj); SharedPtr& operator= (std::nullptr_t); SharedPtr(SharedPtr&& _obj); + template::value + && !std::is_void::value + , int>::type = 0> + SharedPtr(const SharedPtr& _obj); + template::value + && !std::is_void::value + , int>::type = 0> + SharedPtr& operator= (const SharedPtr& _obj); public: template::value @@ -61,44 +88,27 @@ namespace ememory { EMEMORY_TYPE* get(); const EMEMORY_TYPE* operator->() const; EMEMORY_TYPE* operator->(); - #if 0 - template<> - const typename std::enable_if::value, EMEMORY_TYPE>::type& operator*() const { - return *m_element; - } - template<> - typename std::enable_if::value, EMEMORY_TYPE&>::type operator*() { - return *m_element; - } - #else - #if 1 - template::value - && !std::is_void::value - , int>::type> - const EMEMORY_TYPE2& operator*() const { - return *m_element; - } - template::value - && !std::is_void::value - , int>::type> - EMEMORY_TYPE2& operator*() { - return *m_element; - } - #else - const EMEMORY_TYPE& operator*() const { - return *m_element; - } - EMEMORY_TYPE& operator*() { - return *m_element; - } - #endif - #endif + template::value + && !std::is_void::value + , int>::type> + const EMEMORY_TYPE2& operator*() const { + return *m_element; + } + template::value + && !std::is_void::value + , int>::type> + EMEMORY_TYPE2& operator*() { + return *m_element; + } void swap(SharedPtr& _obj); ememory::Counter* getCounter() const { return m_counter; } + deleterCall getDeleter() const { + return m_deleter; + } // TODO: unique // TODO: bool }; diff --git a/ememory/WeakPtr.h b/ememory/WeakPtr.h index 51c6025..5896f4d 100644 --- a/ememory/WeakPtr.h +++ b/ememory/WeakPtr.h @@ -33,6 +33,16 @@ namespace ememory { WeakPtr(const SharedPtr& _obj); WeakPtr& operator= (const SharedPtr& _obj); WeakPtr& operator= (std::nullptr_t); + template::value + && !std::is_void::value + , int>::type = 0> + WeakPtr(const SharedPtr& _obj); + template::value + && !std::is_void::value + , int>::type = 0> + WeakPtr& operator= (const SharedPtr& _obj); public: /* template::type> ememory::SharedPtr::SharedPtr(EMEMORY_TYPE2* _element): m_element(_element), - m_counter(nullptr) { + m_counter(nullptr), + m_deleter(createDeleter(9999)) { EMEMORY_VERBOSE("new shared"); if (m_element == nullptr) { return; @@ -42,7 +43,8 @@ template::type> ememory::SharedPtr::SharedPtr(EMEMORY_TYPE2* _element): m_element(_element), - m_counter(nullptr) { + m_counter(nullptr), + m_deleter(createDeleter(9999)) { EMEMORY_VERBOSE("new shared"); if (m_element == nullptr) { return; @@ -53,21 +55,24 @@ ememory::SharedPtr::SharedPtr(EMEMORY_TYPE2* _element): template ememory::SharedPtr::SharedPtr(): m_element(nullptr), - m_counter(nullptr) { + m_counter(nullptr), + m_deleter(createDeleter(9999)) { EMEMORY_VERBOSE("new shared"); } template ememory::SharedPtr::SharedPtr(std::nullptr_t): m_element(nullptr), - m_counter(nullptr) { + m_counter(nullptr), + m_deleter(createDeleter(9999)) { EMEMORY_VERBOSE("new shared"); } template ememory::SharedPtr::SharedPtr(EMEMORY_TYPE* _obj, ememory::Counter* _counter): m_element(_obj), - m_counter(_counter) { + m_counter(_counter), + m_deleter(createDeleter(9999)) { EMEMORY_VERBOSE("new shared (from a cast)"); if (_obj == nullptr) { m_counter = nullptr; @@ -85,11 +90,13 @@ ememory::SharedPtr::~SharedPtr() { template ememory::SharedPtr::SharedPtr(const ememory::SharedPtr& _obj): m_element(_obj.m_element), - m_counter(_obj.m_counter) { + m_counter(_obj.m_counter), + m_deleter(_obj.m_deleter) { if ( m_element == nullptr || m_counter == nullptr) { m_element = nullptr; m_counter = nullptr; + m_deleter = nullptr; return; } if (m_counter == nullptr) { @@ -102,10 +109,12 @@ template ememory::SharedPtr& ememory::SharedPtr::operator= (const ememory::SharedPtr& _obj) { m_element = _obj.m_element; m_counter = _obj.m_counter; + m_deleter = _obj.m_deleter; if ( m_element == nullptr || m_counter == nullptr) { m_element = nullptr; m_counter = nullptr; + m_deleter = nullptr; return *this; } if (m_counter == nullptr) { @@ -115,6 +124,52 @@ ememory::SharedPtr& ememory::SharedPtr::operator= (c return *this; } +template +template::value + && !std::is_void::value + , int>::type> +ememory::SharedPtr::SharedPtr(const ememory::SharedPtr& _obj): + m_element((void*)_obj.get()), + m_counter(_obj.getCounter()), + m_deleter(nullptr) { // NOTE the deleter does not exist anymore ... + if ( m_element == nullptr + || m_counter == nullptr) { + m_element = nullptr; + m_counter = nullptr; + m_deleter = nullptr; + return; + } + if (m_counter == nullptr) { + return; + } + m_counter->incrementShared(); +} + +template +template::value + && !std::is_void::value + , int>::type> +ememory::SharedPtr& ememory::SharedPtr::operator= (const ememory::SharedPtr& _obj) { + m_element = (void*)_obj.get(); + m_counter = _obj.getCounter(); + m_deleter = nullptr; // NOTE the deleter does not exist anymore ... + if ( m_element == nullptr + || m_counter == nullptr) { + m_element = nullptr; + m_counter = nullptr; + m_deleter = nullptr; + return *this; + } + if (m_counter == nullptr) { + return *this; + } + m_counter->incrementShared(); + return *this; +} + + template ememory::SharedPtr& ememory::SharedPtr::operator= (std::nullptr_t) { reset(); @@ -126,8 +181,10 @@ template ememory::SharedPtr::SharedPtr(ememory::SharedPtr&& _obj) { m_element = _obj.m_element; m_counter = _obj.m_counter; + m_deleter = _obj.m_deleter; _obj.m_element = nullptr; _obj.m_counter = nullptr; + _obj.m_deleter = nullptr; } template @@ -136,7 +193,8 @@ template::type> ememory::SharedPtr::SharedPtr(const ememory::SharedPtr& _obj): m_element(const_cast(_obj.get())), - m_counter(const_cast(_obj.getCounter())) { + m_counter(const_cast(_obj.getCounter())), + m_deleter(createDeleter(9999)) { if ( m_element == nullptr || m_counter == nullptr) { m_element = nullptr; @@ -156,6 +214,7 @@ template& ememory::SharedPtr::operator= (const SharedPtr& _obj) { m_element = const_cast(_obj.get()); m_counter = const_cast(_obj.getCounter()); + m_deleter = createDeleter(9999); if ( m_element == nullptr || m_counter == nullptr) { m_element = nullptr; @@ -173,6 +232,7 @@ template void ememory::SharedPtr::reset() { if(m_counter == nullptr) { m_element = nullptr; // in case ... + m_deleter = nullptr; return; } EMEMORY_VERBOSE("reset sharedPtr (start)"); @@ -180,10 +240,18 @@ void ememory::SharedPtr::reset() { switch(rmData) { case ememory::Counter::remove::all: delete m_counter; - delete m_element; + if (m_deleter != nullptr) { + m_deleter(m_element); + } else { + EMEMORY_WARNING("Maybe a leak ==> no deleter of the SharedPtr"); + } break; case ememory::Counter::remove::data: - delete m_element; + if (m_deleter != nullptr) { + m_deleter(m_element); + } else { + EMEMORY_WARNING("Maybe a leak ==> no deleter of the SharedPtr"); + } break; case ememory::Counter::remove::counter: delete m_counter; @@ -191,6 +259,7 @@ void ememory::SharedPtr::reset() { case ememory::Counter::remove::none: break; } + m_deleter = nullptr; m_counter = nullptr; m_element = nullptr; EMEMORY_VERBOSE("reset sharedPtr (stop)"); @@ -205,7 +274,7 @@ int64_t ememory::SharedPtr::useCount() const { } template -bool ememory::SharedPtr::operator == (std::nullptr_t) const { +bool ememory::SharedPtr::operator==(std::nullptr_t) const { return m_counter == nullptr; } @@ -215,7 +284,7 @@ bool ememory::SharedPtr::operator==(const SharedPtr& _obj) const { } template -bool ememory::SharedPtr::operator != (std::nullptr_t) const { +bool ememory::SharedPtr::operator!=(std::nullptr_t) const { return m_counter != nullptr; } @@ -267,10 +336,13 @@ template void ememory::SharedPtr::swap(SharedPtr& _obj) { EMEMORY_TYPE* tmpE = m_element; ememory::Counter* tmpC = m_counter; + deleterCall* tmpD = m_deleter; m_element = _obj.m_element; m_counter = _obj.m_counter; + m_deleter = _obj.m_deleter; _obj.m_element = tmpE; _obj.m_counter = tmpC; + _obj.m_deleter = tmpD; } diff --git a/ememory/details/WeakPtr.hxx b/ememory/details/WeakPtr.hxx index 1419249..ce67c8c 100644 --- a/ememory/details/WeakPtr.hxx +++ b/ememory/details/WeakPtr.hxx @@ -101,7 +101,7 @@ ememory::WeakPtr::WeakPtr(const ememory::SharedPtr& return; } m_counter->incrementWeak(); -}; +} template @@ -121,6 +121,50 @@ ememory::WeakPtr& ememory::WeakPtr::operator= (const return *this; } + +template +template::value + && !std::is_void::value + , int>::type> +ememory::WeakPtr::WeakPtr(const ememory::SharedPtr& _obj): + m_element((void*)_obj.get()), + m_counter(_obj.getCounter()) { + if ( m_element == nullptr + || m_counter == nullptr) { + m_element = nullptr; + m_counter = nullptr; + return; + } + if (m_counter == nullptr) { + return; + } + m_counter->incrementWeak(); +} + + +template +template::value + && !std::is_void::value + , int>::type> +ememory::WeakPtr& ememory::WeakPtr::operator= (const ememory::SharedPtr& _obj) { + m_element = (void*)_obj.get(); + m_counter = _obj.getCounter(); + if ( m_element == nullptr + || m_counter == nullptr) { + m_element = nullptr; + m_counter = nullptr; + return *this; + } + if (m_counter == nullptr) { + return *this; + } + m_counter->incrementWeak(); + return *this; +} + + /* template::value