[DEV] start dev of smart pointer implementation

This commit is contained in:
Edouard DUPIN 2014-05-15 22:25:06 +02:00
parent 2e98c66894
commit cfbdc0e84e
5 changed files with 212 additions and 16 deletions

2
external/etk vendored

@ -1 +1 @@
Subproject commit d2997292a5c1204d8f38a2d751c5fb416058dc10 Subproject commit b60324928a7d69d2abc7afe4ab726676f560d317

View File

@ -48,7 +48,7 @@ void ewol::object::Manager::unInit() {
iii++; iii++;
} else { } else {
EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\""); EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\"");
delete(m_eObjectList[iii]); m_eObjectList[iii].reset();
m_eObjectList[iii] = NULL; m_eObjectList[iii] = NULL;
} }
} else { } else {
@ -63,8 +63,7 @@ void ewol::object::Manager::unInit() {
iii++; iii++;
} else { } else {
EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\""); EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\"");
delete(m_eObjectList[iii]); m_eObjectList[iii].reset();
m_eObjectList[iii] = NULL;
} }
} else { } else {
m_eObjectList.erase(m_eObjectList.begin()+iii); m_eObjectList.erase(m_eObjectList.begin()+iii);
@ -75,8 +74,7 @@ void ewol::object::Manager::unInit() {
while(iii < m_eObjectList.size()) { while(iii < m_eObjectList.size()) {
if (m_eObjectList[iii] != NULL) { if (m_eObjectList[iii] != NULL) {
EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\""); EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\"");
delete(m_eObjectList[iii]); m_eObjectList[iii].reset();
m_eObjectList[iii] = NULL;
} else { } else {
m_eObjectList.erase(m_eObjectList.begin()+iii); m_eObjectList.erase(m_eObjectList.begin()+iii);
} }
@ -84,11 +82,11 @@ void ewol::object::Manager::unInit() {
} }
void ewol::object::Manager::add(ewol::Object* _object) { void ewol::object::Manager::add(ewol::Object* _object) {
if (NULL != _object) { if (_object == NULL) {
m_eObjectList.push_back(_object);
} else {
EWOL_ERROR("try to add an inexistant Object in manager"); EWOL_ERROR("try to add an inexistant Object in manager");
} }
// ! < it might benerate a shared object !!!
m_eObjectList.push_back(_object);
} }
int32_t ewol::object::Manager::getNumberObject() { int32_t ewol::object::Manager::getNumberObject() {
@ -181,11 +179,8 @@ void ewol::object::Manager::removeAllAutoRemove() {
while(0<m_eObjectAutoRemoveList.size()) { while(0<m_eObjectAutoRemoveList.size()) {
if (m_eObjectAutoRemoveList[0] != NULL) { if (m_eObjectAutoRemoveList[0] != NULL) {
EWOL_DEBUG("Real Auto-Remove Object [" << m_eObjectAutoRemoveList[0]->getId() << "]type='" << m_eObjectAutoRemoveList[0]->getObjectType() << "'"); EWOL_DEBUG("Real Auto-Remove Object [" << m_eObjectAutoRemoveList[0]->getId() << "]type='" << m_eObjectAutoRemoveList[0]->getObjectType() << "'");
delete(m_eObjectAutoRemoveList[0]);
m_eObjectAutoRemoveList[0] = NULL;
} else {
m_eObjectAutoRemoveList.erase(m_eObjectAutoRemoveList.begin());
} }
m_eObjectAutoRemoveList.erase(m_eObjectAutoRemoveList.begin());
} }
m_eObjectAutoRemoveList.clear(); m_eObjectAutoRemoveList.clear();
} }
@ -197,7 +192,7 @@ ewol::Object* ewol::object::Manager::get(const std::string& _name) {
for (size_t iii=0; iii<m_eObjectList.size(); iii++) { for (size_t iii=0; iii<m_eObjectList.size(); iii++) {
if (m_eObjectList[iii] != NULL) { if (m_eObjectList[iii] != NULL) {
if (m_eObjectList[iii]->getName() == _name) { if (m_eObjectList[iii]->getName() == _name) {
return m_eObjectList[iii]; return m_eObjectList[iii].get();
} }
} }
} }

View File

@ -17,8 +17,8 @@ namespace ewol {
namespace object { namespace object {
class Manager { class Manager {
private: private:
std::vector<ewol::Object*> m_eObjectList; // all widget allocated == > all time increment ... never removed ... std::vector<ewol::Object::Shared<ewol::Object>> m_eObjectList; // all widget allocated == > all time increment ... never removed ...
std::vector<ewol::Object*> m_eObjectAutoRemoveList; // all widget allocated std::vector<ewol::Object::Shared<ewol::Object>> m_eObjectAutoRemoveList; // all widget allocated
public: public:
Manager(); Manager();
~Manager(); ~Manager();

View File

@ -19,7 +19,36 @@
const char* const ewol::Object::configName = "name"; const char* const ewol::Object::configName = "name";
size_t ewol::Object::m_valUID = 0; size_t ewol::Object::m_valUID = 0;
void ewol::Object::objRefCountIncrement() {
m_objRefCount++;
}
void ewol::Object::objRefCountDecrement() {
m_objRefCount--;
}
void ewol::Object::operator delete(void* _ptr, std::size_t _sz) {
EWOL_DEBUG("custom delete for size " << _sz);
ewol::Object* obj = (ewol::Object*)_ptr;
obj->objRefCountDecrement();
if (obj->m_objRefCount <= 0) {
EWOL_DEBUG(" ==> real remove");
::operator delete(_ptr);
} else {
EWOL_DEBUG(" ==> Some user is link on it ...");
}
}
void ewol::Object::operator delete[](void* _ptr, std::size_t _sz) {
EWOL_CRITICAL("custom delete for size ==> not implemented ..." << _sz);
::operator delete(_ptr);
}
ewol::Object::Object() : ewol::Object::Object() :
m_objRefCount(1),
m_static(false), m_static(false),
m_isResource(false) { m_isResource(false) {
// note this is nearly atomic ... (but it is enough) // note this is nearly atomic ... (but it is enough)
@ -29,6 +58,7 @@ ewol::Object::Object() :
registerConfig(configName, "string", NULL, "Object name, might be a unique reference in all the program"); registerConfig(configName, "string", NULL, "Object name, might be a unique reference in all the program");
} }
ewol::Object::Object(const std::string& _name) : ewol::Object::Object(const std::string& _name) :
m_objRefCount(1),
m_static(false), m_static(false),
m_name(_name), m_name(_name),
m_isResource(false) { m_isResource(false) {

View File

@ -47,6 +47,92 @@ namespace ewol {
* this class mermit at every Object to communicate between them. * this class mermit at every Object to communicate between them.
*/ */
class Object { class Object {
public:
template<typename T, typename = typename std::enable_if<std::is_convertible<T*, Object*>::value>::type>
class Shared {
private:
T* m_pointer;
public:
Shared() :
m_pointer(nullptr) {
// nothing to do ...
}
Shared(T* _pointer) :
m_pointer(_pointer) {
if (m_pointer == nullptr) {
return;
}
m_pointer->objRefCountIncrement();
}
~Shared() {
reset();
}
// copy constructor
Shared(const Shared& _obj) :
m_pointer(nullptr) {
m_pointer = _obj.get();
if (m_pointer == nullptr) {
return;
}
m_pointer->objRefCountIncrement();
}
// Move Constructor
Shared(Shared&& _obj) :
m_pointer(nullptr) {
// transfert pointer
m_pointer = _obj.m_pointer;
_obj.m_pointer = nullptr;
}
Shared& operator=(const Shared<T>& _obj) noexcept {
if(this == &_obj) {
return *this;
}
reset();
m_pointer = _obj.get();
if (m_pointer != nullptr) {
m_pointer->objRefCountIncrement();
}
return *this;
}
void reset() {
if (m_pointer == nullptr) {
return;
}
if (m_pointer->m_objRefCount <= 0) {
TK_ERROR("Object is already removed");
} else if (m_pointer->m_objRefCount == 1) {
TK_ERROR("Remove object (in shared)");
delete m_pointer;
} else {
m_pointer->objRefCountDecrement();
}
m_pointer = nullptr;
}
T* get() noexcept {
return m_pointer;
}
T* get() const noexcept {
return m_pointer;
}
T& operator*() const noexcept {
return *m_pointer;
}
T* operator->() const noexcept {
return m_pointer;
}
};
template<typename T> Shared<T> makeShared(T* _pointer) {
return Shared<T>(_pointer);
}
private:
// TODO : Lock Refcounting ...
int32_t m_objRefCount;
public:
void objRefCountIncrement();
void objRefCountDecrement();
static void operator delete(void* _ptr, std::size_t _sz);
static void operator delete[](void* _ptr, std::size_t _sz);
private: private:
static size_t m_valUID; //!< stic used for the unique ID definition static size_t m_valUID; //!< stic used for the unique ID definition
public: public:
@ -302,6 +388,91 @@ namespace ewol {
return m_isResource; return m_isResource;
} }
}; };
// section to compare shared pointer of an object with an other
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const Object::Shared<T>& _obj, const Object::Shared<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc
template<typename T2>
inline bool operator==(const Object::Shared<T2>& _obj, std::nullptr_t) noexcept {
return _obj.get() == NULL;
}
//! @not in doc
template<typename T2>
inline bool operator==(std::nullptr_t, const Object::Shared<T2>& _obj) noexcept {
return _obj.get() == NULL;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator==(const Object::Shared<T>& _obj, const T2* _obj2) noexcept {
return _obj.get() == _obj2;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator==(const T* _obj, const Object::Shared<T2>& _obj2) noexcept {
return _obj == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const Object::Shared<T>& _obj, const Object::Shared<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc
template<typename T>
inline bool operator!=(const Object::Shared<T>& _obj, std::nullptr_t) noexcept {
return _obj.get() != NULL;
}
//! @not in doc
template<typename T>
inline bool operator!=(std::nullptr_t, const Object::Shared<T>& _obj) noexcept {
return _obj.get() != NULL;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator!=(const Object::Shared<T>& _obj, const T2* _obj2) noexcept {
return _obj.get() != _obj2;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator!=(const T* _obj, const Object::Shared<T2>& _obj2) noexcept {
return _obj != _obj2.get();
}
//! @not in doc
template<typename T>
inline void swap(Object::Shared<T>& _obj, Object::Shared<T>& _obj2) noexcept {
_obj2.swap(_obj);
}
//! @not in doc
template<typename T2, typename T>
inline Object::Shared<T2> static_pointer_cast(const Object::Shared<T>& _obj) noexcept {
return Object::Shared<T2>(_obj, static_cast<T2*>(_obj.get()));
}
//! @not in doc
template<typename T2, typename T>
inline Object::Shared<T2> const_pointer_cast(const Object::Shared<T>& _obj) noexcept {
return Object::Shared<T2>(_obj, const_cast<T2*>(_obj.get()));
}
//! @not in doc
template<typename T2, typename T>
inline Object::Shared<T2> dynamic_pointer_cast(const Object::Shared<T>& _obj) noexcept {
if (T2* obj = dynamic_cast<T2*>(_obj.get())) {
return Object::Shared<T2>(_obj, obj);
}
return Object::Shared<T2>();
}
}; };
#endif #endif