[DEV] SharedPtr work ... but now I have the constness of sub element when SharedPtr is const (good pointinstead of the std)

This commit is contained in:
Edouard DUPIN 2016-07-14 23:58:54 +02:00
parent b271ad15ad
commit 39e7d4103e
13 changed files with 292 additions and 37 deletions

View File

@ -23,12 +23,12 @@ ememory::Counter::~Counter() {
EMEMORY_VERBOSE("delete counter"); EMEMORY_VERBOSE("delete counter");
} }
int64_t ememory::Counter::incrementShared() { int64_t ememory::Counter::incrementShared(bool _fromWeak) {
int64_t out; int64_t out;
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
EMEMORY_VERBOSE("shared++ (start) ==> w:" << m_counterWeak << " s:" << m_counterShared); EMEMORY_VERBOSE("shared++ (start) ==> w:" << m_counterWeak << " s:" << m_counterShared);
if (m_counterShared != 0) { if (m_counterShared != 0 || _fromWeak == false) {
m_counterShared++; m_counterShared++;
} }
out = m_counterShared; out = m_counterShared;

View File

@ -27,7 +27,7 @@ namespace ememory {
public: public:
Counter(bool _fromWeak=false); Counter(bool _fromWeak=false);
~Counter(); ~Counter();
int64_t incrementShared(); int64_t incrementShared(bool _fromWeak=false);
ememory::Counter::remove decrementShared(); ememory::Counter::remove decrementShared();
int64_t incrementWeak(); int64_t incrementWeak();
ememory::Counter::remove decrementWeak(); ememory::Counter::remove decrementWeak();

View File

@ -22,7 +22,9 @@ namespace ememory {
virtual ~EnableSharedFromThis() = default; virtual ~EnableSharedFromThis() = default;
public: public:
ememory::SharedPtr<EMEMORY_TYPE> sharedFromThis(); ememory::SharedPtr<EMEMORY_TYPE> sharedFromThis();
const ememory::SharedPtr<EMEMORY_TYPE> sharedFromThis() const;
ememory::WeakPtr<EMEMORY_TYPE> weakFromThis(); ememory::WeakPtr<EMEMORY_TYPE> weakFromThis();
const ememory::WeakPtr<EMEMORY_TYPE> weakFromThis() const;
}; };
} }

View File

@ -9,9 +9,11 @@
#include <mutex> #include <mutex>
#include <ememory/debug.h> #include <ememory/debug.h>
#include <ememory/Counter.h> #include <ememory/Counter.h>
#include <ememory/EnableSharedFromThis.h>
namespace ememory { namespace ememory {
template<typename> class WeakPtr; template<typename> class WeakPtr;
template<typename> class EnableSharedFromThis;
// limited implementation of actual shared pointer (only 1 instance allowed, can be promoted though) // limited implementation of actual shared pointer (only 1 instance allowed, can be promoted though)
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
class SharedPtr { class SharedPtr {
@ -20,26 +22,50 @@ namespace ememory {
EMEMORY_TYPE* m_element; EMEMORY_TYPE* m_element;
ememory::Counter* m_counter; ememory::Counter* m_counter;
public: public:
SharedPtr(EMEMORY_TYPE* _element); template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
&& std::is_base_of<ememory::EnableSharedFromThis<EMEMORY_TYPE2>, EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr(EMEMORY_TYPE2* _element);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
&& !std::is_base_of<ememory::EnableSharedFromThis<EMEMORY_TYPE2>, EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr(EMEMORY_TYPE2* _element);
public: public:
SharedPtr(); SharedPtr();
~SharedPtr(); ~SharedPtr();
SharedPtr(const SharedPtr& _obj); SharedPtr(EMEMORY_TYPE* _obj, ememory::Counter* _counter);
SharedPtr& operator= (const SharedPtr& _obj); SharedPtr(const SharedPtr<EMEMORY_TYPE>& _obj);
SharedPtr(SharedPtr&& _obj); SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE>& _obj);
SharedPtr& operator= (std::nullptr_t);
SharedPtr(SharedPtr<EMEMORY_TYPE>&& _obj);
public:
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr(const SharedPtr<EMEMORY_TYPE2>& _obj);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE2>& _obj);
public:
void reset(); void reset();
int64_t useCount() const; int64_t useCount() const;
bool operator == (std::nullptr_t); bool operator == (std::nullptr_t) const;
bool operator==(const SharedPtr& _obj) const; bool operator==(const SharedPtr<EMEMORY_TYPE>& _obj) const;
bool operator != (std::nullptr_t); bool operator != (std::nullptr_t) const;
bool operator!=(const SharedPtr& _obj) const; bool operator!=(const SharedPtr<EMEMORY_TYPE>& _obj) const;
const EMEMORY_TYPE* get() const; const EMEMORY_TYPE* get() const;
EMEMORY_TYPE* get(); EMEMORY_TYPE* get();
const EMEMORY_TYPE* operator->() const; const EMEMORY_TYPE* operator->() const;
EMEMORY_TYPE* operator->(); EMEMORY_TYPE* operator->();
const EMEMORY_TYPE& operator*() const; const EMEMORY_TYPE& operator*() const;
EMEMORY_TYPE& operator*(); EMEMORY_TYPE& operator*();
void swap(SharedPtr& _obj); void swap(SharedPtr<EMEMORY_TYPE>& _obj);
ememory::Counter* getCounter() const {
return m_counter;
}
}; };
} }

View File

@ -16,6 +16,7 @@ namespace ememory {
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
class WeakPtr { class WeakPtr {
friend class EnableSharedFromThis<EMEMORY_TYPE>; friend class EnableSharedFromThis<EMEMORY_TYPE>;
friend class SharedPtr<EMEMORY_TYPE>;
private: private:
EMEMORY_TYPE* m_element; EMEMORY_TYPE* m_element;
ememory::Counter* m_counter; ememory::Counter* m_counter;
@ -30,13 +31,31 @@ namespace ememory {
WeakPtr(WeakPtr&& _obj); WeakPtr(WeakPtr&& _obj);
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);
public:
/*
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type = 0>
WeakPtr(const WeakPtr<EMEMORY_TYPE2>& _obj);
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type = 0>
WeakPtr& operator= (const WeakPtr<EMEMORY_TYPE2>& _obj);
*/
public:
void reset(); void reset();
int useCount() const; int useCount() const;
bool expired() const; bool expired() const;
ememory::SharedPtr<EMEMORY_TYPE> lock(); ememory::SharedPtr<EMEMORY_TYPE> lock();
bool operator == (const WeakPtr& _obj); bool operator==(const WeakPtr& _obj);
bool operator == (std::nullptr_t); bool operator==(std::nullptr_t) const;
bool operator!=(const WeakPtr& _obj);
bool operator!=(std::nullptr_t) const;
void swap(WeakPtr& _obj); void swap(WeakPtr& _obj);
ememory::Counter* getCounter() const {
return m_counter;
}
}; };
} }

View File

@ -11,7 +11,7 @@
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::EnableSharedFromThis<EMEMORY_TYPE>::EnableSharedFromThis() : ememory::EnableSharedFromThis<EMEMORY_TYPE>::EnableSharedFromThis() :
m_weakThis(static_cast<EMEMORY_TYPE*>(this)) { m_weakThis(static_cast<EMEMORY_TYPE*>(this)) {
EMEMORY_VERBOSE("create shared from this ...");
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
@ -19,8 +19,18 @@ ememory::SharedPtr<EMEMORY_TYPE> ememory::EnableSharedFromThis<EMEMORY_TYPE>::sh
return m_weakThis.lock(); return m_weakThis.lock();
} }
template<typename EMEMORY_TYPE>
const ememory::SharedPtr<EMEMORY_TYPE> ememory::EnableSharedFromThis<EMEMORY_TYPE>::sharedFromThis() const{
return m_weakThis.lock();
}
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::WeakPtr<EMEMORY_TYPE> ememory::EnableSharedFromThis<EMEMORY_TYPE>::weakFromThis() { ememory::WeakPtr<EMEMORY_TYPE> ememory::EnableSharedFromThis<EMEMORY_TYPE>::weakFromThis() {
return m_weakThis; return m_weakThis;
} }
template<typename EMEMORY_TYPE>
const ememory::WeakPtr<EMEMORY_TYPE> ememory::EnableSharedFromThis<EMEMORY_TYPE>::weakFromThis() const {
return m_weakThis;
}

View File

@ -11,7 +11,11 @@
#include <ememory/WeakPtr.h> #include <ememory/WeakPtr.h>
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE* _element): template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
&& std::is_base_of<ememory::EnableSharedFromThis<EMEMORY_TYPE2>, EMEMORY_TYPE2>::value
, int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element):
m_element(_element), m_element(_element),
m_counter(nullptr) { m_counter(nullptr) {
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
@ -19,19 +23,24 @@ ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE* _element):
return; return;
} }
// check if the clas does not refer itself ... to get his own sharedPtr // check if the clas does not refer itself ... to get his own sharedPtr
ememory::EnableSharedFromThis<EMEMORY_TYPE> upperClass = static_cast<ememory::EnableSharedFromThis<EMEMORY_TYPE>*>(m_element); ememory::EnableSharedFromThis<EMEMORY_TYPE2>* upperClass = static_cast<ememory::EnableSharedFromThis<EMEMORY_TYPE2>*>(m_element);
if (upperClass != nullptr) { if (upperClass != nullptr) {
m_counter = upperClass->m_weakThis; EMEMORY_VERBOSE(" ==> get previous pointer");
m_counter = upperClass->m_weakThis.m_counter;
if (m_counter != nullptr) { if (m_counter != nullptr) {
m_counter->incrementShared(); m_counter->incrementShared();
} }
} else { return;
m_counter = new ememory::Counter(false);
} }
EMEMORY_ERROR("No counter on a shared ptr class (EnableSharedFromThis ==> this is bad");
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE* _element): template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
&& !std::is_base_of<ememory::EnableSharedFromThis<EMEMORY_TYPE2>, EMEMORY_TYPE2>::value
, int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE2* _element):
m_element(_element), m_element(_element),
m_counter(nullptr) { m_counter(nullptr) {
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
@ -48,6 +57,18 @@ ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr():
EMEMORY_VERBOSE("new shared"); EMEMORY_VERBOSE("new shared");
} }
template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(EMEMORY_TYPE* _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();
}
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>::~SharedPtr() { ememory::SharedPtr<EMEMORY_TYPE>::~SharedPtr() {
EMEMORY_VERBOSE("delete shared"); EMEMORY_VERBOSE("delete shared");
@ -87,6 +108,13 @@ ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (c
return *this; return *this;
} }
template<typename EMEMORY_TYPE>
ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (std::nullptr_t) {
reset();
return *this;
}
template<typename EMEMORY_TYPE> 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;
@ -95,6 +123,45 @@ ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(ememory::SharedPtr<EMEMORY_TYPE>&& _
_obj.m_counter = nullptr; _obj.m_counter = nullptr;
} }
template<typename EMEMORY_TYPE>
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type>
ememory::SharedPtr<EMEMORY_TYPE>::SharedPtr(const ememory::SharedPtr<EMEMORY_TYPE2>& _obj):
m_element(const_cast<EMEMORY_TYPE2*>(_obj.get())),
m_counter(const_cast<ememory::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<typename EMEMORY_TYPE>
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type>
ememory::SharedPtr<EMEMORY_TYPE>& ememory::SharedPtr<EMEMORY_TYPE>::operator= (const SharedPtr<EMEMORY_TYPE2>& _obj) {
m_element = const_cast<EMEMORY_TYPE2*>(_obj.get());
m_counter = const_cast<ememory::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;
}
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
void ememory::SharedPtr<EMEMORY_TYPE>::reset() { void ememory::SharedPtr<EMEMORY_TYPE>::reset() {
if(m_counter == nullptr) { if(m_counter == nullptr) {
@ -131,7 +198,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) { bool ememory::SharedPtr<EMEMORY_TYPE>::operator == (std::nullptr_t) const {
return m_counter == nullptr; return m_counter == nullptr;
} }
@ -141,7 +208,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) { bool ememory::SharedPtr<EMEMORY_TYPE>::operator != (std::nullptr_t) const {
return m_counter != nullptr; return m_counter != nullptr;
} }

View File

@ -66,6 +66,12 @@ ememory::WeakPtr<EMEMORY_TYPE>& ememory::WeakPtr<EMEMORY_TYPE>::operator= (const
return *this; return *this;
} }
template<typename EMEMORY_TYPE>
ememory::WeakPtr<EMEMORY_TYPE>& ememory::WeakPtr<EMEMORY_TYPE>::operator= (std::nullptr_t) {
reset();
return *this;
}
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
ememory::WeakPtr<EMEMORY_TYPE>::WeakPtr(ememory::WeakPtr<EMEMORY_TYPE>&& _obj) { ememory::WeakPtr<EMEMORY_TYPE>::WeakPtr(ememory::WeakPtr<EMEMORY_TYPE>&& _obj) {
m_element = _obj.m_element; m_element = _obj.m_element;
@ -108,6 +114,44 @@ ememory::WeakPtr<EMEMORY_TYPE>& ememory::WeakPtr<EMEMORY_TYPE>::operator= (const
return *this; return *this;
} }
/*
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type>
WeakPtr(const WeakPtr<EMEMORY_TYPE2>& _obj):
m_element(_obj.m_element),
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<class EMEMORY_TYPE2,
typename std::enable_if< std::is_base_of<EMEMORY_TYPE, EMEMORY_TYPE2>::value
, int>::type>
WeakPtr& operator= (const WeakPtr<EMEMORY_TYPE2>& _obj) {
m_element = _obj.m_element;
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<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
void ememory::WeakPtr<EMEMORY_TYPE>::reset() { void ememory::WeakPtr<EMEMORY_TYPE>::reset() {
if(m_counter == nullptr) { if(m_counter == nullptr) {
@ -154,7 +198,7 @@ ememory::SharedPtr<EMEMORY_TYPE> ememory::WeakPtr<EMEMORY_TYPE>::lock() {
if (m_counter == nullptr) { if (m_counter == nullptr) {
return out; return out;
} }
int64_t count = m_counter->incrementShared(); int64_t count = m_counter->incrementShared(true);
if (count == 0) { if (count == 0) {
return out; return out;
} }
@ -164,15 +208,25 @@ ememory::SharedPtr<EMEMORY_TYPE> ememory::WeakPtr<EMEMORY_TYPE>::lock() {
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
bool ememory::WeakPtr<EMEMORY_TYPE>::operator == (const ememory::WeakPtr<EMEMORY_TYPE>& _obj) { bool ememory::WeakPtr<EMEMORY_TYPE>::operator==(const ememory::WeakPtr<EMEMORY_TYPE>& _obj) {
return m_counter == _obj.m_counter; return m_counter == _obj.m_counter;
} }
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
bool ememory::WeakPtr<EMEMORY_TYPE>::operator == (std::nullptr_t) { bool ememory::WeakPtr<EMEMORY_TYPE>::operator==(std::nullptr_t) const {
return m_counter == nullptr; return m_counter == nullptr;
} }
template<typename EMEMORY_TYPE>
bool ememory::WeakPtr<EMEMORY_TYPE>::operator!=(const ememory::WeakPtr<EMEMORY_TYPE>& _obj) {
return m_counter != _obj.m_counter;
}
template<typename EMEMORY_TYPE>
bool ememory::WeakPtr<EMEMORY_TYPE>::operator!=(std::nullptr_t) const {
return m_counter != nullptr;
}
template<typename EMEMORY_TYPE> template<typename EMEMORY_TYPE>
void ememory::WeakPtr<EMEMORY_TYPE>::swap(ememory::WeakPtr<EMEMORY_TYPE>& _obj) { void ememory::WeakPtr<EMEMORY_TYPE>::swap(ememory::WeakPtr<EMEMORY_TYPE>& _obj) {
EMEMORY_TYPE* tmpE = m_element; EMEMORY_TYPE* tmpE = m_element;

View File

@ -12,8 +12,36 @@
#include <ememory/EnableSharedFromThis.h> #include <ememory/EnableSharedFromThis.h>
namespace ememory { namespace ememory {
template<class EMEMORY_TYPE, typename... EMEMORY_ARGS> template<class EMEMORY_TYPE, typename... EMEMORY_ARGS>
static ememory::SharedPtr<EMEMORY_TYPE> makeShared(EMEMORY_ARGS && ...args) { static ememory::SharedPtr<EMEMORY_TYPE> makeShared(EMEMORY_ARGS && ..._args) {
return ememory::SharedPtr<EMEMORY_TYPE>(new EMEMORY_TYPE(std::forward<EMEMORY_ARGS>(args)...)); return ememory::SharedPtr<EMEMORY_TYPE>(new EMEMORY_TYPE(std::forward<EMEMORY_ARGS>(_args)...));
}
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline ememory::SharedPtr<EMEMORY_TYPE_CAST> dynamicPointerCast(ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(dynamic_cast<EMEMORY_TYPE_CAST*>(_obj.get()), _obj.getCounter());
}
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline const ememory::SharedPtr<EMEMORY_TYPE_CAST> dynamicPointerCast(const ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(dynamic_cast<EMEMORY_TYPE_CAST*>(_obj.get()), _obj.getCounter());
}
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline ememory::SharedPtr<EMEMORY_TYPE_CAST> staticPointerCast(ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(static_cast<EMEMORY_TYPE_CAST*>(_obj.get()), _obj.getCounter());
}
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline const ememory::SharedPtr<EMEMORY_TYPE_CAST> staticPointerCast(const ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(static_cast<EMEMORY_TYPE_CAST*>(_obj.get()), _obj.getCounter());
}
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline ememory::SharedPtr<EMEMORY_TYPE_CAST> reinterpretPointerCast(ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(reinterpret_cast<EMEMORY_TYPE_CAST*>(_obj.get()), _obj.getCounter());
}
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline const ememory::SharedPtr<EMEMORY_TYPE_CAST> reinterpretPointerCast(const ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(reinterpret_cast<EMEMORY_TYPE_CAST*>(_obj.get()), _obj.getCounter());
} }
} }

View File

@ -0,0 +1,55 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <ememory/memory.h>
#include "main.h"
namespace testEnableCast {
class testClass {
public:
testClass() {
EMEMORY_INFO("create TestClass");
}
virtual ~testClass() {
EMEMORY_INFO("delete TestClass");
}
};
class testClassChild : public testEnableCast::testClass {
public:
testClassChild() {
EMEMORY_INFO("create TestClassChild");
}
~testClassChild() {
EMEMORY_INFO("delete TestClassChild");
}
};
}
TEST(TestEnableCast, base) {
ememory::SharedPtr<testEnableCast::testClassChild> dataChild = ememory::makeShared<testEnableCast::testClassChild>();
EXPECT_EQ(dataChild.useCount(), 1);
ememory::SharedPtr<testEnableCast::testClass> data = dataChild;
EXPECT_EQ(dataChild.useCount(), 2);
EXPECT_EQ(data.useCount(), 2);
ememory::SharedPtr<testEnableCast::testClassChild> dataChildStatic = ememory::staticPointerCast<testEnableCast::testClassChild>(data);
EXPECT_EQ(dataChild.useCount(), 3);
EXPECT_EQ(data.useCount(), 3);
EXPECT_EQ(dataChildStatic.useCount(), 3);
ememory::SharedPtr<testEnableCast::testClassChild> dataChildDynamic = ememory::dynamicPointerCast<testEnableCast::testClassChild>(data);
EXPECT_EQ(dataChild.useCount(), 4);
EXPECT_EQ(data.useCount(), 4);
EXPECT_EQ(dataChildStatic.useCount(), 4);
EXPECT_EQ(dataChildDynamic.useCount(), 4);
ememory::SharedPtr<testEnableCast::testClassChild> dataChildReinterpret = ememory::reinterpretPointerCast<testEnableCast::testClassChild>(data);
EXPECT_EQ(dataChild.useCount(), 5);
EXPECT_EQ(data.useCount(), 5);
EXPECT_EQ(dataChildStatic.useCount(), 5);
EXPECT_EQ(dataChildDynamic.useCount(), 5);
EXPECT_EQ(dataChildReinterpret.useCount(), 5);
}

View File

@ -1,8 +1,6 @@
/** @file /** @file
* @author Edouard DUPIN * @author Edouard DUPIN
* * @copyright 2016, Edouard DUPIN, all right reserved
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */

View File

@ -1,8 +1,6 @@
/** @file /** @file
* @author Edouard DUPIN * @author Edouard DUPIN
* * @copyright 2016, Edouard DUPIN, all right reserved
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */

View File

@ -1,8 +1,6 @@
/** @file /** @file
* @author Edouard DUPIN * @author Edouard DUPIN
* * @copyright 2016, Edouard DUPIN, all right reserved
* @copyright 2014, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file) * @license APACHE v2.0 (see license file)
*/ */