[DEV] update donumentation

This commit is contained in:
Edouard DUPIN 2016-09-13 22:31:35 +02:00
parent 74f4716d83
commit 18ed76c268
8 changed files with 375 additions and 49 deletions

View File

@ -4,7 +4,7 @@ EMEMORY library {#mainpage}
What is EMEMORY, and how can I use it?
--------------------------------------
EMEMORY, or Ewol Memory interface is a simple abstraction layer over std::shared_ptr.
EMEMORY, or Ewol Memory interface is a simple abstraction layer over std::shared_ptr.
EMEMORY is designed for:
- Permit to change the backend of shered_ptr when we want

View File

@ -27,5 +27,9 @@ def create(target, module_name):
'*.h',
'*.md',
])
my_module.add_module_define([
"PARSE_DOXYGEN",
])
return my_module

View File

@ -12,27 +12,69 @@
#include <stdint.h>
namespace ememory {
/**
* @brief Couter is an important part of the SharedPtr/WeakPtr implementation. This use a simple refcounting method dut thread-safe
*/
class Counter {
public:
/**
* @brief Remove case of the counter. When decrese the shared our weak counter, it is the upper class that need to remove the counter of the data pointer
*/
enum class remove {
none,
data,
counter,
all
none, //!< Noting to remove
data, //!< Remove only the data
counter, //!< Remove only the Counter (data already removed)
all //!< Remove Data and Counter
};
private:
int64_t m_counterShared;
int64_t m_counterWeak;
mutable std::mutex m_mutex;
int64_t m_counterShared; //!< Count of the active SharedPtr
int64_t m_counterWeak; //!< Count of the active WeakPtr
mutable std::mutex m_mutex; //!< local counter mutex to prevent the thread concurent removing
public:
/**
* @brief Contructor
* @param[in] _fromWeak Counter is created from a WeakPtr instead of a SharedPtr
*/
Counter(bool _fromWeak=false);
/**
* @brief Destrunctor (Not virtual !!)
*/
~Counter();
/**
* @brief Increment the shared counter (one more shared user)
* @param[in] _fromWeak At true if the increment came from a WeakPtr instead of a SharedPtr
* @return Number of current SharedPtr that has been curently access at this data. Return 0 if the increment is not possible (object has no more SharedPtr)
*/
int64_t incrementShared(bool _fromWeak=false);
/**
* @brief Decrese of 1 the shared counter
* @return The action to do on the pointer or the counter
*/
ememory::Counter::remove decrementShared();
/**
* @brief Increment the weak counter (one more weak user)
* @return Number of current WeakPtr that has been curently access at this data.
*/
int64_t incrementWeak();
/**
* @brief Decrese of 1 the weak counter
* @return The action to do on the pointer or the counter
*/
ememory::Counter::remove decrementWeak();
/**
* @brief Get the number of weak counter
* @return Number of WeakPtr connected.
*/
int64_t getCountWeak() const;
/**
* @brief Get the number of shared counter
* @return Number of SharedPtr connected.
*/
int64_t getCountShared() const;
/**
* @brief Get the number of weak+shared counter
* @return Number of WeakPtr and SharedPtr connected.
*/
int64_t getCount() const;
};
}

View File

@ -12,18 +12,46 @@
namespace ememory {
/**
* @brief Basic handle to be simplify at the basic mode of the onject recognition for internal tamplate filter (empty implementation)
*/
class EnableSharedFromThisBase {};
/**
* @brief Enable the acces of the self sharedPtr inside an object (note: not availlable in contructor and destructor)
*/
template<typename EMEMORY_TYPE>
class EnableSharedFromThis : public ememory::EnableSharedFromThisBase {
private:
mutable ememory::WeakPtr<EMEMORY_TYPE> m_weakThis;
mutable ememory::WeakPtr<EMEMORY_TYPE> m_weakThis; //!< Weak pointer reference of itself.
protected:
/**
* @brief Contructor
*/
EnableSharedFromThis();
/**
* @brief Virual destructor (simply virtualyse the destructor)
*/
virtual ~EnableSharedFromThis() = default;
public:
/**
* @brief Get the currect class SharedPtr
* @return Request SharedPtr
*/
ememory::SharedPtr<EMEMORY_TYPE> sharedFromThis();
/**
* @brief Get the currect class SharedPtr
* @return Request const SharedPtr
*/
const ememory::SharedPtr<EMEMORY_TYPE> sharedFromThis() const;
/**
* @brief Get the currect class WeakPtr
* @return Request WeakPtr
*/
ememory::WeakPtr<EMEMORY_TYPE> weakFromThis();
/**
* @brief Get the currect class WeakPtr
* @return Request const WeakPtr
*/
const ememory::WeakPtr<EMEMORY_TYPE> weakFromThis() const;
};
}

View File

@ -15,65 +15,185 @@ namespace ememory {
template<typename> class WeakPtr;
template<typename> class EnableSharedFromThis;
using deleterCall = std::function<void(void* _data)>;
// limited implementation of actual shared pointer (only 1 instance allowed, can be promoted though)
/**
* @brief ememory::SharedPtr is a smart pointer that retains shared ownership of an object through a pointer.
* Several SharedPtr objects may own the same object. The object is destroyed and its memory deallocated when
* either of the following happens:
* - the last remaining SharedPtr owning the object is destroyed;
* - the last remaining SharedPtr owning the object is assigned another pointer via operator= or reset().
* The object is destroyed using delete-expression or a custom deleter that is supplied to shared_ptr during construction.
*
* A SharedPtr can share ownership of an object while storing a pointer to another object.
* This feature can be used to point to member objects while owning the object they belong to.
* The stored pointer is the one accessed by get(), the dereference and the comparison operators.
* The managed pointer is the one passed to the deleter when use count reaches zero.
*
* @note A big difference whith this wrapper is the constness sharing. When your sharedPtr is shared, the internal pointer is shared too.
*/
template<typename EMEMORY_TYPE>
class SharedPtr {
friend class WeakPtr<EMEMORY_TYPE>;
private:
EMEMORY_TYPE* m_element;
ememory::Counter* m_counter;
deleterCall m_deleter;
EMEMORY_TYPE* m_element; //!< Pointer on the Data
ememory::Counter* m_counter; //!< Pointer on the counter
deleterCall m_deleter; //!< Function to call to delete the data pointer
/**
* @brief Create the function to remove the pointer of the data
* @return deleter function (need access to a voind data access)
*/
deleterCall createDeleter() const {
return [](void* _data) { delete((EMEMORY_TYPE*)_data);};
}
public:
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
&& std::is_base_of<ememory::EnableSharedFromThisBase, 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::EnableSharedFromThisBase, EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr(EMEMORY_TYPE2* _element);
#ifndef PARSE_DOXYGEN
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_same<EMEMORY_TYPE2, EMEMORY_TYPE>::value
&& std::is_base_of<ememory::EnableSharedFromThisBase, 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::EnableSharedFromThisBase, EMEMORY_TYPE2>::value
, int>::type = 0>
SharedPtr(EMEMORY_TYPE2* _element);
#else
/**
* @brief Contructor whith the pointer of data
* @param[in] _element allocated data (SharedPtr will remove it)
*/
SharedPtr(EMEMORY_TYPE2* _element);
#endif
public:
/**
* @brief Contructor on nullptr
*/
SharedPtr(std::nullptr_t);
/**
* @brief Contructor empty
*/
SharedPtr();
~SharedPtr();
/**
* @brief Contructor (API for casting)
* @param[in] _obj Pointer on the Data
* @param[in] _counter Pointer on the counter
*/
SharedPtr(EMEMORY_TYPE* _obj, ememory::Counter* _counter);
/**
* @brief copy Contructor
* @param[in] _obj SharedPtr to copy
*/
SharedPtr(const SharedPtr<EMEMORY_TYPE>& _obj);
SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE>& _obj);
SharedPtr& operator= (std::nullptr_t);
/**
* @brief copy Contructor
* @param[in] _obj SharedPtr to copy
*/
SharedPtr(SharedPtr<EMEMORY_TYPE>&& _obj);
/**
* @brief Destructor
*/
~SharedPtr();
/**
* @brief Asignement operator
* @param[in] _obj SharedPtr to copy
* @return Reference on this
*/
SharedPtr& operator= (const SharedPtr<EMEMORY_TYPE>& _obj);
/**
* @brief Asignement operator (asign nullptr)
* @return Reference on this
*/
SharedPtr& 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>
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);
#ifndef PARSE_DOXYGEN
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);
#endif
public:
/**
* @brief Reset the SharedPtr ==> Remove data if needed
*/
void reset();
/**
* @brief Get the number of conencted SharedPtr
* @return Number of SharedPtr on this data
*/
int64_t useCount() const;
/**
* @brief Check if the SharedPtr have an internal data (not nullptr)
* @return true The pointer is not asigned, false otherwise
*/
bool operator==(std::nullptr_t) const;
/**
* @brief Check if two SharedPtr are the same data (maybe not the same cast)
* @param[in] _obj Object to compare
* @return true The Object have the same pointer reference, false otherwise
*/
template<class EMEMORY_TYPE2>
bool operator==(const SharedPtr<EMEMORY_TYPE2>& _obj) const;
/**
* @brief Check if the SharedPtr have NOT an internal data (nullptr)
* @return true The pointer is asigned, false otherwise
*/
bool operator!=(std::nullptr_t) const;
/**
* @brief Check if two SharedPtr are NOT the same data (maybe not the same cast)
* @param[in] _obj Object to compare
* @return true The Object have NOT the same pointer reference, false otherwise
*/
template<class EMEMORY_TYPE2>
bool operator!=(const SharedPtr<EMEMORY_TYPE2>& _obj) const;
/**
* @brief Get a const pointer on the data
* @return Data const pointer
*/
const EMEMORY_TYPE* get() const;
/**
* @brief Get a pointer on the data
* @return Data pointer
*/
EMEMORY_TYPE* get();
/**
* @brief Const dereferences the stored pointer.
* @return Const pointer on the Data
*/
const EMEMORY_TYPE* operator->() const;
/**
* @brief Dereferences the stored pointer.
* @return Pointer on the Data
*/
EMEMORY_TYPE* operator->();
/**
* @brief Get a const reference on the data
* @return Data const reference
*/
const EMEMORY_TYPE& operator*() const;
/**
* @brief Get a reference on the data
* @return Data reference
*/
EMEMORY_TYPE& operator*();
/**
* @brief Swap 2 Object inside the SharedPtr
* @param[in] _obj Object to swap with
*/
void swap(SharedPtr<EMEMORY_TYPE>& _obj);
/**
* @brief Get Counter pointer
* @return Pointer on the counter
*/
ememory::Counter* getCounter() const {
return m_counter;
}
/**
* @brief Get deleter function of the data pointer
* @return deleter function
*/
deleterCall getDeleter() const {
return m_deleter;
}

View File

@ -14,30 +14,78 @@ namespace ememory {
template<typename> class SharedPtr;
template<typename> class EnableSharedFromThis;
template<typename EMEMORY_TYPE>
/**
* @brief WeakPtr is an interface that lose the data pointer when all SharedPtr as been released
*/
class WeakPtr {
friend class EnableSharedFromThis<EMEMORY_TYPE>;
friend class SharedPtr<EMEMORY_TYPE>;
private:
EMEMORY_TYPE* m_element;
ememory::Counter* m_counter;
EMEMORY_TYPE* m_element; //!< Pointer on the Data
ememory::Counter* m_counter; //!< Pointer on the counter
public:
/**
* @brief Empty Contructor
*/
WeakPtr();
/**
* @brief nullptr contructor
*/
WeakPtr(std::nullptr_t);
private:
/**
* @brief Contructor of the Weak Ptr (specific for EnableSharedFromThis)
* @param[in] _element Pointer on data
*/
WeakPtr(EMEMORY_TYPE* _element); // this is only for enable shared from this ...
public:
~WeakPtr();
/**
* @brief Copy contuctor
* @param[in] _obj Object to copy
*/
WeakPtr(const WeakPtr<EMEMORY_TYPE>& _obj);
/**
* @brief Const copy asignement
* @param[in] _obj Object to copy
* @return Reference on this
*/
WeakPtr<EMEMORY_TYPE>& operator= (const WeakPtr<EMEMORY_TYPE>& _obj);
/**
* @brief Copy contructor
* @param[in] _obj Object to copy
*/
WeakPtr(WeakPtr&& _obj);
/**
* @brief Const copy asignement
* @param[in] _obj Object to copy
*/
WeakPtr(const SharedPtr<EMEMORY_TYPE>& _obj);
/**
* @brief Const copy asignement
* @param[in] _obj Object to copy
* @return Reference on this
*/
WeakPtr<EMEMORY_TYPE>& operator= (const SharedPtr<EMEMORY_TYPE>& _obj);
/**
* @brief nullptr asignement
* @return Reference on this
*/
WeakPtr<EMEMORY_TYPE>& operator= (std::nullptr_t);
/**
* @brief Copy contuctor of herited WeakPtr
* @param[in] _obj Object to copy
*/
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);
/**
* @brief Const copy asignement of herited WeakPtr
* @param[in] _obj Object to copy
* @return Reference on this
*/
template<class EMEMORY_TYPE2,
typename std::enable_if< std::is_void<EMEMORY_TYPE>::value
&& !std::is_void<EMEMORY_TYPE2>::value
@ -55,15 +103,57 @@ namespace ememory {
WeakPtr& operator= (const WeakPtr<EMEMORY_TYPE2>& _obj);
*/
public:
/**
* @brief Reset the WeakPtr ==> Remove data if needed
*/
void reset();
/**
* @brief Get the number of conencted SharedPtr
* @return Number of SharedPtr on this data
*/
int useCount() const;
/**
* @brief Get the status of the pointer
* @return true if the Pointer is lockable
* @note The status chan change in an other thread release the SharedPtr
*/
bool expired() const;
/**
* @brief Lock in SharedPtr the current Weak pointer
* @return created SharedPtr
*/
ememory::SharedPtr<EMEMORY_TYPE> lock();
/**
* @brief Check if two WeakPtr are the same data
* @param[in] _obj Object to compare
* @return true The Object have the same pointer reference, false otherwise
*/
bool operator==(const WeakPtr& _obj);
/**
* @brief Check if the WeakPtr have an internal data (not nullptr)
* @return true The pointer is not asigned, false otherwise
*/
bool operator==(std::nullptr_t) const;
/**
* @brief Check if two WeakPtr are different data
* @param[in] _obj Object to compare
* @return true The Object have NOT the same pointer reference, false otherwise
*/
bool operator!=(const WeakPtr& _obj);
/**
* @brief Check if the SharedPtr have NOT an internal data (nullptr)
* @return true The pointer is asigned, false otherwise
*/
bool operator!=(std::nullptr_t) const;
/**
* @brief Swap 2 Object inside the WeakPtr
* @param[in] _obj Object to swap with
*/
void swap(WeakPtr& _obj);
/**
* @brief Get Counter pointer
* @return Pointer on the counter
*/
ememory::Counter* getCounter() const {
return m_counter;
}

View File

@ -11,40 +11,78 @@
#include <ememory/WeakPtr.h>
#include <ememory/EnableSharedFromThis.h>
/**
* @brief Ememory is a namespace to represent the @code #include <memory> @endcode part ==> simple memory access abstraction
*/
namespace ememory {
/**
* @brief Create a SharedPtr with specific arguments
* @param[in] _args Multiples argument to add in the EMEMORY_TYPE public constructor.
* @return the requested created SharedPtr
*/
template<class EMEMORY_TYPE, typename... EMEMORY_ARGS>
static ememory::SharedPtr<EMEMORY_TYPE> makeShared(EMEMORY_ARGS && ..._args) {
return ememory::SharedPtr<EMEMORY_TYPE>(new EMEMORY_TYPE(std::forward<EMEMORY_ARGS>(_args)...));
}
/**
* @brief Cast in Dynamic the input SharedPtr into an other type like dynamic_cast on pointer
* @param[in] _obj Object To cast
* @return Casted Object
*/
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());
}
/**
* @brief CONST Cast in Dynamic the input SharedPtr into an other type like dynamic_cast on pointer
* @param[in] _obj Object To cast
* @return Casted Object
*/
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*>(const_cast<EMEMORY_TYPE*>(_obj.get())), _obj.getCounter());
}
/**
* @brief Cast in static the input SharedPtr into an other type like static_cast on pointer
* @param[in] _obj Object To cast
* @return Casted Object
*/
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());
}
/**
* @brief CONST Cast in static the input SharedPtr into an other type like static_cast on pointer
* @param[in] _obj Object To cast
* @return Casted Object
*/
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*>(const_cast<EMEMORY_TYPE*>(_obj.get())), _obj.getCounter());
}
/**
* @brief Cast in reinterpret the input SharedPtr into an other type like reinterpret_cast on pointer
* @param[in] _obj Object To cast
* @return Casted Object
*/
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());
}
/**
* @brief CONST Cast in reinterpret the input SharedPtr into an other type like reinterpret_cast on pointer
* @param[in] _obj Object To cast
* @return Casted Object
*/
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*>(const_cast<EMEMORY_TYPE*>(_obj.get())), _obj.getCounter());
}
/**
* @brief Cast in const the input SharedPtr into an other type like const_cast on pointer (remove constness)
* @param[in] _obj Object To cast
* @return Casted Object
*/
template<class EMEMORY_TYPE_CAST, class EMEMORY_TYPE>
inline ememory::SharedPtr<EMEMORY_TYPE_CAST> constPointerCast(const ememory::SharedPtr<EMEMORY_TYPE>& _obj) {
return ememory::SharedPtr<EMEMORY_TYPE_CAST>(const_cast<EMEMORY_TYPE*>(_obj.get()), _obj.getCounter());

View File

@ -10,7 +10,7 @@ def get_sub_type():
return "TEST"
def get_desc():
return "eSVG test-unit"
return "e-memory test-unit"
def get_licence():
return "APACHE-2"
@ -27,12 +27,16 @@ def get_maintainer():
def create(target, module_name):
my_module = module.Module(__file__, module_name, get_type())
my_module.add_src_file([
'test/main.cpp',
'test/testShared.cpp',
'test/testWeak.cpp',
'test/testEnableSharedFromThis.cpp',
'test/testCasts.cpp'
])
my_module.add_depend(['ememory', 'gtest', 'test-debug'])
'test/main.cpp',
'test/testShared.cpp',
'test/testWeak.cpp',
'test/testEnableSharedFromThis.cpp',
'test/testCasts.cpp'
])
my_module.add_depend([
'ememory',
'gtest',
'test-debug'
])
return my_module