[DEV] continue integrate void sharedPtr

This commit is contained in:
Edouard DUPIN 2016-07-18 02:03:32 +02:00
parent 447ae56fd5
commit 98063cdbef
4 changed files with 182 additions and 46 deletions

View File

@ -18,9 +18,26 @@ namespace ememory {
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
class SharedPtr { class SharedPtr {
friend class WeakPtr<EMEMORY_TYPE>; friend class WeakPtr<EMEMORY_TYPE>;
public:
using deleterCall = std::function<void(EMEMORY_TYPE* _data)>;
private: private:
EMEMORY_TYPE* m_element; EMEMORY_TYPE* m_element;
ememory::Counter* m_counter; ememory::Counter* m_counter;
deleterCall m_deleter;
template<class EMEMORY_TYPE2,
typename std::enable_if< !std::is_void<EMEMORY_TYPE>::value
&& std::is_integral<EMEMORY_TYPE2>::value
, int>::type = 0>
deleterCall createDeleter(EMEMORY_TYPE2) const {
return [](EMEMORY_TYPE* _data) { delete(_data);};
}
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& std::is_integral<EMEMORY_TYPE2>::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: public:
template<class EMEMORY_TYPE2, template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
@ -41,6 +58,16 @@ namespace ememory {
SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE>& _obj); SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE>& _obj);
SharedPtr& operator= (std::nullptr_t); SharedPtr& operator= (std::nullptr_t);
SharedPtr(SharedPtr<EMEMORY_TYPE>&& _obj); SharedPtr(SharedPtr<EMEMORY_TYPE>&& _obj);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr(const SharedPtr<EMEMORY_TYPE2>& _obj);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE2>& _obj);
public: public:
template<class EMEMORY_TYPE2, template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
@ -61,44 +88,27 @@ namespace ememory {
EMEMORY_TYPE* get(); EMEMORY_TYPE* get();
const EMEMORY_TYPE* operator->() const; const EMEMORY_TYPE* operator->() const;
EMEMORY_TYPE* operator->(); EMEMORY_TYPE* operator->();
#if 0 template<class EMEMORY_TYPE2,
template<> typename std::enable_if< !std::is_void<EMEMORY_TYPE>::value
const typename std::enable_if<!std::is_void<EMEMORY_TYPE>::value, EMEMORY_TYPE>::type& operator*() const { && !std::is_void<EMEMORY_TYPE2>::value
return *m_element; , int>::type>
} const EMEMORY_TYPE2& operator*() const {
template<> return *m_element;
typename std::enable_if<!std::is_void<EMEMORY_TYPE>::value, EMEMORY_TYPE&>::type operator*() { }
return *m_element; template<class EMEMORY_TYPE2,
} typename std::enable_if< !std::is_void<EMEMORY_TYPE>::value
#else && !std::is_void<EMEMORY_TYPE2>::value
#if 1 , int>::type>
template<class EMEMORY_TYPE2, EMEMORY_TYPE2& operator*() {
typename std::enable_if< !std::is_void<EMEMORY_TYPE>::value return *m_element;
&& !std::is_void<EMEMORY_TYPE2>::value }
, int>::type>
const EMEMORY_TYPE2& operator*() const {
return *m_element;
}
template<class EMEMORY_TYPE2,
typename std::enable_if< !std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::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
void swap(SharedPtr<EMEMORY_TYPE>& _obj); void swap(SharedPtr<EMEMORY_TYPE>& _obj);
ememory::Counter* getCounter() const { ememory::Counter* getCounter() const {
return m_counter; return m_counter;
} }
deleterCall getDeleter() const {
return m_deleter;
}
// TODO: unique // TODO: unique
// TODO: bool // TODO: bool
}; };

View File

@ -33,6 +33,16 @@ namespace ememory {
WeakPtr(const SharedPtr<EMEMORY_TYPE>& _obj); WeakPtr(const SharedPtr<EMEMORY_TYPE>& _obj);
WeakPtr<EMEMORY_TYPE>& operator= (const SharedPtr<EMEMORY_TYPE>& _obj); WeakPtr<EMEMORY_TYPE>& operator= (const SharedPtr<EMEMORY_TYPE>& _obj);
WeakPtr<EMEMORY_TYPE>& operator= (std::nullptr_t); WeakPtr<EMEMORY_TYPE>& operator= (std::nullptr_t);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type = 0>
WeakPtr(const SharedPtr<EMEMORY_TYPE2>& _obj);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type = 0>
WeakPtr<EMEMORY_TYPE>& operator= (const SharedPtr<EMEMORY_TYPE2>& _obj);
public: public:
/* /*
template<class EMEMORY_TYPE2, template<class EMEMORY_TYPE2,

View File

@ -17,7 +17,8 @@ template<class EMEMORY_TYPE2,
, int>::type> , int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element):
m_element(_element), m_element(_element),
m_counter(nullptr) { m_counter(nullptr),
m_deleter(createDeleter(9999)) {
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
if (m_element == nullptr) { if (m_element == nullptr) {
return; return;
@ -42,7 +43,8 @@ template<class EMEMORY_TYPE2,
, int>::type> , int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element):
m_element(_element), m_element(_element),
m_counter(nullptr) { m_counter(nullptr),
m_deleter(createDeleter(9999)) {
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
if (m_element == nullptr) { if (m_element == nullptr) {
return; return;
@ -53,21 +55,24 @@ ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element):
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr():
m_element(nullptr), m_element(nullptr),
m_counter(nullptr) { m_counter(nullptr),
m_deleter(createDeleter(9999)) {
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(std::nullptr_t): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(std::nullptr_t):
m_element(nullptr), m_element(nullptr),
m_counter(nullptr) { m_counter(nullptr),
m_deleter(createDeleter(9999)) {
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE* _obj, ememory::Counter* _counter): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE* _obj, ememory::Counter* _counter):
m_element(_obj), m_element(_obj),
m_counter(_counter) { m_counter(_counter),
m_deleter(createDeleter(9999)) {
EMEMORY_VERBOSE("new shared (from a cast)"); EMEMORY_VERBOSE("new shared (from a cast)");
if (_obj == nullptr) { if (_obj == nullptr) {
m_counter = nullptr; m_counter = nullptr;
@ -85,11 +90,13 @@ ememory::SharedPtr<EMEMORY_TYPE>::~SharedPtr() {
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(const ememory::SharedPtr<EMEMORY_TYPE>& _obj): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(const ememory::SharedPtr<EMEMORY_TYPE>& _obj):
m_element(_obj.m_element), m_element(_obj.m_element),
m_counter(_obj.m_counter) { m_counter(_obj.m_counter),
m_deleter(_obj.m_deleter) {
if ( m_element == nullptr if ( m_element == nullptr
|| m_counter == nullptr) { || m_counter == nullptr) {
m_element = nullptr; m_element = nullptr;
m_counter = nullptr; m_counter = nullptr;
m_deleter = nullptr;
return; return;
} }
if (m_counter == nullptr) { if (m_counter == nullptr) {
@ -102,10 +109,12 @@ template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (const ememory::SharedPtr<EMEMORY_TYPE>& _obj) { ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (const ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
m_element = _obj.m_element; m_element = _obj.m_element;
m_counter = _obj.m_counter; m_counter = _obj.m_counter;
m_deleter = _obj.m_deleter;
if ( m_element == nullptr if ( m_element == nullptr
|| m_counter == nullptr) { || m_counter == nullptr) {
m_element = nullptr; m_element = nullptr;
m_counter = nullptr; m_counter = nullptr;
m_deleter = nullptr;
return *this; return *this;
} }
if (m_counter == nullptr) { if (m_counter == nullptr) {
@ -115,6 +124,52 @@ ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (c
return *this; return *this;
} }
template<typename EMEMORY_TYPE>
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(const ememory::SharedPtr<EMEMORY_TYPE2>& _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<typename EMEMORY_TYPE>
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type>
ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (const ememory::SharedPtr<EMEMORY_TYPE2>& _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<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (std::nullptr_t) { ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (std::nullptr_t) {
reset(); reset();
@ -126,8 +181,10 @@ template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(ememory::SharedPtr<EMEMORY_TYPE>&& _obj) { ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(ememory::SharedPtr<EMEMORY_TYPE>&& _obj) {
m_element = _obj.m_element; m_element = _obj.m_element;
m_counter = _obj.m_counter; m_counter = _obj.m_counter;
m_deleter = _obj.m_deleter;
_obj.m_element = nullptr; _obj.m_element = nullptr;
_obj.m_counter = nullptr; _obj.m_counter = nullptr;
_obj.m_deleter = nullptr;
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
@ -136,7 +193,8 @@ template<class EMEMORY_TYPE2,
, int>::type> , int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(const ememory::SharedPtr<EMEMORY_TYPE2>& _obj): ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(const ememory::SharedPtr<EMEMORY_TYPE2>& _obj):
m_element(const_cast<EMEMORY_TYPE2*>(_obj.get())), m_element(const_cast<EMEMORY_TYPE2*>(_obj.get())),
m_counter(const_cast<ememory::Counter*>(_obj.getCounter())) { m_counter(const_cast<ememory::Counter*>(_obj.getCounter())),
m_deleter(createDeleter(9999)) {
if ( m_element == nullptr if ( m_element == nullptr
|| m_counter == nullptr) { || m_counter == nullptr) {
m_element = nullptr; m_element = nullptr;
@ -156,6 +214,7 @@ template<class EMEMORY_TYPE2,
ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (const SharedPtr<EMEMORY_TYPE2>& _obj) { ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (const SharedPtr<EMEMORY_TYPE2>& _obj) {
m_element = const_cast<EMEMORY_TYPE2*>(_obj.get()); m_element = const_cast<EMEMORY_TYPE2*>(_obj.get());
m_counter = const_cast<ememory::Counter*>(_obj.getCounter()); m_counter = const_cast<ememory::Counter*>(_obj.getCounter());
m_deleter = createDeleter(9999);
if ( m_element == nullptr if ( m_element == nullptr
|| m_counter == nullptr) { || m_counter == nullptr) {
m_element = nullptr; m_element = nullptr;
@ -173,6 +232,7 @@ template<typename EMEMORY_TYPE>
void ememory::SharedPtr<EMEMORY_TYPE>::reset() { void ememory::SharedPtr<EMEMORY_TYPE>::reset() {
if(m_counter == nullptr) { if(m_counter == nullptr) {
m_element = nullptr; // in case ... m_element = nullptr; // in case ...
m_deleter = nullptr;
return; return;
} }
EMEMORY_VERBOSE("reset sharedPtr (start)"); EMEMORY_VERBOSE("reset sharedPtr (start)");
@ -180,10 +240,18 @@ void ememory::SharedPtr<EMEMORY_TYPE>::reset() {
switch(rmData) { switch(rmData) {
case ememory::Counter::remove::all: case ememory::Counter::remove::all:
delete m_counter; 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; break;
case ememory::Counter::remove::data: 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; break;
case ememory::Counter::remove::counter: case ememory::Counter::remove::counter:
delete m_counter; delete m_counter;
@ -191,6 +259,7 @@ void ememory::SharedPtr<EMEMORY_TYPE>::reset() {
case ememory::Counter::remove::none: case ememory::Counter::remove::none:
break; break;
} }
m_deleter = nullptr;
m_counter = nullptr; m_counter = nullptr;
m_element = nullptr; m_element = nullptr;
EMEMORY_VERBOSE("reset sharedPtr (stop)"); EMEMORY_VERBOSE("reset sharedPtr (stop)");
@ -205,7 +274,7 @@ int64_t ememory::SharedPtr<EMEMORY_TYPE>::useCount() const {
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
bool ememory::SharedPtr<EMEMORY_TYPE>::operator == (std::nullptr_t) const { bool ememory::SharedPtr<EMEMORY_TYPE>::operator==(std::nullptr_t) const {
return m_counter == nullptr; return m_counter == nullptr;
} }
@ -215,7 +284,7 @@ bool ememory::SharedPtr<EMEMORY_TYPE>::operator==(const SharedPtr& _obj) const {
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
bool ememory::SharedPtr<EMEMORY_TYPE>::operator != (std::nullptr_t) const { bool ememory::SharedPtr<EMEMORY_TYPE>::operator!=(std::nullptr_t) const {
return m_counter != nullptr; return m_counter != nullptr;
} }
@ -267,10 +336,13 @@ template<typename EMEMORY_TYPE>
void ememory::SharedPtr<EMEMORY_TYPE>::swap(SharedPtr& _obj) { void ememory::SharedPtr<EMEMORY_TYPE>::swap(SharedPtr& _obj) {
EMEMORY_TYPE* tmpE = m_element; EMEMORY_TYPE* tmpE = m_element;
ememory::Counter* tmpC = m_counter; ememory::Counter* tmpC = m_counter;
deleterCall* tmpD = m_deleter;
m_element = _obj.m_element; m_element = _obj.m_element;
m_counter = _obj.m_counter; m_counter = _obj.m_counter;
m_deleter = _obj.m_deleter;
_obj.m_element = tmpE; _obj.m_element = tmpE;
_obj.m_counter = tmpC; _obj.m_counter = tmpC;
_obj.m_deleter = tmpD;
} }

View File

@ -101,7 +101,7 @@ ememory::WeakPtr<EMEMORY_TYPE>::WeakPtr(const ememory::SharedPtr<EMEMORY_TYPE>&
return; return;
} }
m_counter->incrementWeak(); m_counter->incrementWeak();
}; }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
@ -121,6 +121,50 @@ ememory::WeakPtr<EMEMORY_TYPE>& ememory::WeakPtr<EMEMORY_TYPE>::operator= (const
return *this; return *this;
} }
template<typename EMEMORY_TYPE>
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type>
ememory::WeakPtr<EMEMORY_TYPE>::WeakPtr(const ememory::SharedPtr<EMEMORY_TYPE2>& _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<typename EMEMORY_TYPE>
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
, int>::type>
ememory::WeakPtr<EMEMORY_TYPE>& ememory::WeakPtr<EMEMORY_TYPE>::operator= (const ememory::SharedPtr<EMEMORY_TYPE2>& _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<class EMEMORY_TYPE2, template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value