diff --git a/ememory/SharedPtr.h b/ememory/SharedPtr.h index 5419e1a..6678431 100644 --- a/ememory/SharedPtr.h +++ b/ememory/SharedPtr.h @@ -14,29 +14,17 @@ namespace ememory { template class WeakPtr; template class EnableSharedFromThis; + using deleterCall = std::function; // limited implementation of actual shared pointer (only 1 instance allowed, can be promoted though) 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");}; + deleterCall createDeleter() const { + return [](void* _data) { delete((EMEMORY_TYPE*)_data);}; } public: template& _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 @@ -81,27 +59,17 @@ namespace ememory { void reset(); int64_t useCount() const; bool operator==(std::nullptr_t) const; - bool operator==(const SharedPtr& _obj) const; + template + bool operator==(const SharedPtr& _obj) const; bool operator!=(std::nullptr_t) const; - bool operator!=(const SharedPtr& _obj) const; + template + bool operator!=(const SharedPtr& _obj) const; const EMEMORY_TYPE* get() const; EMEMORY_TYPE* get(); const EMEMORY_TYPE* operator->() const; EMEMORY_TYPE* operator->(); - 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; - } + const EMEMORY_TYPE& operator*() const; + EMEMORY_TYPE& operator*(); void swap(SharedPtr& _obj); ememory::Counter* getCounter() const { return m_counter; diff --git a/ememory/details/SharedPtr.hxx b/ememory/details/SharedPtr.hxx index 3ebd157..52794a9 100644 --- a/ememory/details/SharedPtr.hxx +++ b/ememory/details/SharedPtr.hxx @@ -18,7 +18,7 @@ template::SharedPtr(EMEMORY_TYPE2* _element): m_element(_element), m_counter(nullptr), - m_deleter(createDeleter(9999)) { + m_deleter(createDeleter()) { EMEMORY_VERBOSE("new shared"); if (m_element == nullptr) { return; @@ -44,7 +44,7 @@ template::SharedPtr(EMEMORY_TYPE2* _element): m_element(_element), m_counter(nullptr), - m_deleter(createDeleter(9999)) { + m_deleter(createDeleter()) { EMEMORY_VERBOSE("new shared"); if (m_element == nullptr) { return; @@ -56,7 +56,7 @@ template ememory::SharedPtr::SharedPtr(): m_element(nullptr), m_counter(nullptr), - m_deleter(createDeleter(9999)) { + m_deleter(createDeleter()) { EMEMORY_VERBOSE("new shared"); } @@ -64,7 +64,7 @@ template ememory::SharedPtr::SharedPtr(std::nullptr_t): m_element(nullptr), m_counter(nullptr), - m_deleter(createDeleter(9999)) { + m_deleter(createDeleter()) { EMEMORY_VERBOSE("new shared"); } @@ -72,7 +72,7 @@ template ememory::SharedPtr::SharedPtr(EMEMORY_TYPE* _obj, ememory::Counter* _counter): m_element(_obj), m_counter(_counter), - m_deleter(createDeleter(9999)) { + m_deleter(createDeleter()) { EMEMORY_VERBOSE("new shared (from a cast)"); if (_obj == nullptr) { m_counter = nullptr; @@ -124,52 +124,6 @@ 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(); @@ -194,7 +148,7 @@ template::SharedPtr(const ememory::SharedPtr& _obj): m_element(const_cast(_obj.get())), m_counter(const_cast(_obj.getCounter())), - m_deleter(createDeleter(9999)) { + m_deleter(createDeleter()) { if ( m_element == nullptr || m_counter == nullptr) { m_element = nullptr; @@ -214,7 +168,7 @@ template& ememory::SharedPtr::operator= (const SharedPtr& _obj) { m_element = const_cast(_obj.get()); m_counter = const_cast(_obj.getCounter()); - m_deleter = createDeleter(9999); + m_deleter = createDeleter(); if ( m_element == nullptr || m_counter == nullptr) { m_element = nullptr; @@ -241,14 +195,14 @@ void ememory::SharedPtr::reset() { case ememory::Counter::remove::all: delete m_counter; if (m_deleter != nullptr) { - m_deleter(m_element); + m_deleter((void*)m_element); } else { EMEMORY_WARNING("Maybe a leak ==> no deleter of the SharedPtr"); } break; case ememory::Counter::remove::data: if (m_deleter != nullptr) { - m_deleter(m_element); + m_deleter((void*)m_element); } else { EMEMORY_WARNING("Maybe a leak ==> no deleter of the SharedPtr"); } @@ -279,8 +233,9 @@ bool ememory::SharedPtr::operator==(std::nullptr_t) const { } template -bool ememory::SharedPtr::operator==(const SharedPtr& _obj) const { - return m_counter == _obj.m_counter; +template +bool ememory::SharedPtr::operator==(const SharedPtr& _obj) const { + return m_counter == _obj.getCounter(); } template @@ -289,8 +244,9 @@ bool ememory::SharedPtr::operator!=(std::nullptr_t) const { } template -bool ememory::SharedPtr::operator!=(const SharedPtr& _obj) const { - return m_counter != _obj.m_counter; +template +bool ememory::SharedPtr::operator!=(const SharedPtr& _obj) const { + return m_counter != _obj.getCounter(); } template @@ -312,31 +268,23 @@ template EMEMORY_TYPE* ememory::SharedPtr::operator->() { return m_element; } -/* + template -template::value - && !std::is_void::value - , int>::type> const EMEMORY_TYPE& ememory::SharedPtr::operator*() const { return *m_element; } template -template::value - && !std::is_void::value - , int>::type> EMEMORY_TYPE& ememory::SharedPtr::operator*() { return *m_element; } -*/ + template void ememory::SharedPtr::swap(SharedPtr& _obj) { EMEMORY_TYPE* tmpE = m_element; ememory::Counter* tmpC = m_counter; - deleterCall* tmpD = m_deleter; + deleterCall tmpD = m_deleter; m_element = _obj.m_element; m_counter = _obj.m_counter; m_deleter = _obj.m_deleter; @@ -346,3 +294,179 @@ void ememory::SharedPtr::swap(SharedPtr& _obj) { } + + + + + + + + + + + + + + + + + + + + +/////////////////////////////////////////////////////////////////// +// void ... +/////////////////////////////////////////////////////////////////// +namespace ememory { + // Void template specification ... + template<> + class SharedPtr { + friend class WeakPtr; + public: + using deleterCall = std::function; + private: + void* m_element; + ememory::Counter* m_counter; + public: + SharedPtr(void* _element); + public: + SharedPtr(std::nullptr_t): + m_element(nullptr), + m_counter(nullptr) { + EMEMORY_VERBOSE("new shared"); + } + SharedPtr(): + m_element(nullptr), + m_counter(nullptr) { + EMEMORY_VERBOSE("new shared"); + } + ~SharedPtr() { + EMEMORY_VERBOSE("delete shared"); + reset(); + } + SharedPtr(void* _obj, ememory::Counter* _counter): + m_element(_obj), + m_counter(_counter) { + EMEMORY_VERBOSE("new shared (from a cast)"); + if (_obj == nullptr) { + m_counter = nullptr; + return; + } + m_counter->incrementShared(); + } + SharedPtr& operator= (std::nullptr_t) { + reset(); + return *this; + } + SharedPtr(SharedPtr&& _obj) { + m_element = _obj.m_element; + m_counter = _obj.m_counter; + _obj.m_element = nullptr; + _obj.m_counter = nullptr; + } + template + SharedPtr(const 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->incrementShared(); + } + template + SharedPtr& operator= (const 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->incrementShared(); + return *this; + } + public: + void reset() { + if(m_counter == nullptr) { + m_element = nullptr; // in case ... + return; + } + EMEMORY_VERBOSE("reset sharedPtr (start)"); + ememory::Counter::remove rmData = m_counter->decrementShared(); + switch(rmData) { + case ememory::Counter::remove::all: + delete m_counter; + EMEMORY_WARNING("Maybe a leak ==> no deleter of the SharedPtr"); + break; + case ememory::Counter::remove::data: + EMEMORY_WARNING("Maybe a leak ==> no deleter of the SharedPtr"); + break; + case ememory::Counter::remove::counter: + delete m_counter; + break; + case ememory::Counter::remove::none: + break; + } + m_counter = nullptr; + m_element = nullptr; + EMEMORY_VERBOSE("reset sharedPtr (stop)"); + } + int64_t useCount() const { + if (m_counter == nullptr) { + return 0; + } + return m_counter->getCountShared(); + } + bool operator==(std::nullptr_t) const { + return m_counter == nullptr; + } + template + bool operator==(const SharedPtr& _obj) const { + return m_counter == _obj.m_counter; + } + bool operator!=(std::nullptr_t) const { + return m_counter != nullptr; + } + template + bool operator!=(const SharedPtr& _obj) const { + return m_counter != _obj.m_counter; + } + const void* get() const { + return m_element; + } + void* get() { + return m_element; + } + const void* operator->() const { + return m_element; + } + void* operator->() { + return m_element; + } + void swap(SharedPtr& _obj) { + void* tmpE = m_element; + ememory::Counter* tmpC = m_counter; + m_element = _obj.m_element; + m_counter = _obj.m_counter; + _obj.m_element = tmpE; + _obj.m_counter = tmpC; + } + ememory::Counter* getCounter() const { + return m_counter; + } + // TODO: unique + // TODO: bool + }; +} + + diff --git a/test/testShared.cpp b/test/testShared.cpp index 68e0c8b..f0a6580 100644 --- a/test/testShared.cpp +++ b/test/testShared.cpp @@ -57,4 +57,28 @@ TEST(TestShared, callOperator) { EXPECT_EQ(data->size(), 6); } +static void functionCallRef(std::string& _data) { + _data = "plop"; +} + +TEST(TestShared, callOperatorStar) { + ememory::SharedPtr data = ememory::makeShared("coucou"); + EXPECT_EQ(data->size(), 6); + EXPECT_EQ(*data, "coucou"); + *data = "ragout"; + EXPECT_EQ(data->size(), 6); + EXPECT_EQ(*data, "ragout"); + functionCallRef(*data); + EXPECT_EQ(data->size(), 4); + EXPECT_EQ(*data, "plop"); +} + +TEST(TestShared, setInVoid) { + ememory::SharedPtr data = ememory::makeShared("coucou"); + ememory::SharedPtr dataVoid(data); + ememory::SharedPtr dataVoid2; + dataVoid2 = data; + EXPECT_EQ(data.useCount(), 3); +} +