[DEV] update to the new ETK allocator wrapper

This commit is contained in:
Edouard DUPIN 2017-10-21 19:05:21 +02:00
parent 49f30a03e0
commit dab27cb361
9 changed files with 674 additions and 132 deletions

View File

@ -208,7 +208,8 @@ int32_t etest::runAllTest() {
if (it->getTestGroup() != itGroup) {
continue;
}
#if ETK_MEMORY_CHECKER >= 0
bool localFail = false;
#if ETK_MEMORY_CHECKER > 0
uint64_t* memorySnapShoot = etk::memory::createSnapshoot();
#endif
{
@ -222,16 +223,23 @@ int32_t etest::runAllTest() {
if (it->getError() == true) {
ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")");
errorCount++;
localFail = true;
} else {
ETEST_PRINT("[ OK ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")");
}
}
#if ETK_MEMORY_CHECKER >= 0
#if ETK_MEMORY_CHECKER > 0
ETEST_DEBUG("[ MEM ] CHECK memory properties");
bool ret = etk::memory::checkSnapshoot(memorySnapShoot);
etk::memory::clearSnapshoot(memorySnapShoot);
memorySnapShoot = nullptr;
ETEST_DEBUG("[ MEM ] CHECK memory properties (done)");
if (ret == false) {
if (localFail == false) {
errorCount++;
}
ETEST_PRINT("[ FAIL ] " << itGroup << "." << it->getTestName() << " ==> in memory LEAK test");
}
#endif
}
echrono::Steady tocGroup = echrono::Steady::now();

View File

@ -109,11 +109,11 @@ class MemoryElementSystem {
size_t sizeUser; //!< User request size
size_t sizeAllocate; //!< data size really allocated by the tool
size_t sizeData; //!< current data size of allocated memory
size_t id; //!< Element ID to know the allocation Order
#if ETK_MEMORY_CHECKER > 1
size_t id; //!< Element ID to know the allocation Order
char variableName[ETK_MEM_MAX_STRING_SIZE]; //!< Variable name when allocate
char functionName[ETK_MEM_MAX_STRING_SIZE]; //!< function name that allocate this buffer
char fileName[ETK_MEM_MAX_STRING_SIZE]; //!< function name that allocate this buffer
const char* variableName; //!< Variable name when allocate
const char* functionName; //!< function name that allocate this buffer
const char* fileName; //!< function name that allocate this buffer
size_t functionLine; //!< function line where the buffer was allocated
#endif
};
@ -261,6 +261,7 @@ class memoryAllocatorHandle {
memcpy(tmp, m_memListElements, sizeof(MemoryElementSystem) * m_memListElementSize / 2);
delete[] m_memListElements;
m_memListElements = tmp;
ETK_MEMORY_DEBUG("Realloate the allocator memory system: %ld (done)", uint64_t(m_memListElementSize));
// try again
for (size_t iii=0; iii<m_memListElementSize; ++iii) {
if (m_memListElements[iii].used == false) {
@ -353,19 +354,20 @@ class memoryAllocatorHandle {
void displayMemoryProperty(MemoryElementSystem& _element) {
#if ETK_MEMORY_CHECKER > 1
bool errorOccured = false;
ETK_MEMORY_WARNING("Not FREE : %p ==> %p : %ld Bytes var=%s",
ETK_MEMORY_WARNING("Not FREE : %p ==> %p : %ld Bytes var=%s id=%ld",
_element.pointerAllocated,
_element.pointerGiveToUser,
_element.sizeUser,
_element.variableName);
(_element.variableName==nullptr?"---":_element.variableName),
_element.id);
ETK_MEMORY_WARNING("%8d : %s() line=%ld file=%s",
(uint32_t)_element.id,
_element.functionName,
(_element.functionName==nullptr?"---":_element.functionName),
_element.functionLine,
_element.fileName);
(_element.fileName==nullptr?"---":_element.fileName));
if (checkMem(_element.pointerAllocated) == true) {
ETK_MEMORY_ERROR("MEM LOG (L): %s : %ld Bytes @ %p ==> user @ %p (depassement pre)",
_element.variableName,
(_element.variableName==nullptr?"---":_element.variableName),
_element.sizeUser,
_element.pointerAllocated,
_element.pointerGiveToUser);
@ -373,7 +375,7 @@ class memoryAllocatorHandle {
}
if (checkMem(_element.pointerAllocated + _element.sizeUser + m_checkBorneSize) == true) {
ETK_MEMORY_ERROR("MEM LOG (L): %s : %ld Bytes @ %p ==> user @ %p (depassement post)",
_element.variableName,
(_element.variableName==nullptr?"---":_element.variableName),
_element.sizeUser,
_element.pointerAllocated,
_element.pointerGiveToUser);
@ -385,10 +387,10 @@ class memoryAllocatorHandle {
assert(false);
}
#else
ETK_MEMORY_WARNING("Not LOG : %p ==> %p : %d Bytes",
ETK_MEMORY_WARNING("Not LOG : %p ==> %p : %ld Bytes",
_element.pointerAllocated,
_element.pointerGiveToUser,
_element.sizeUser);
uint64_t(_element.sizeUser));
#endif
}
@ -410,7 +412,7 @@ class memoryAllocatorHandle {
countElement = 0;
for (size_t iii=0; iii<m_memListElementSize; ++iii) {
if (m_memListElements[iii].used == true) {
out[countElement++] = uint64_t(m_memListElements[iii].pointerAllocated);
out[countElement++] = uint64_t(m_memListElements[iii].id);
}
}
unLock();
@ -429,7 +431,7 @@ class memoryAllocatorHandle {
bool find = false;
size_t jjj = 0;
while (dataBase[jjj] != 0) {
if (dataBase[jjj] == uint64_t(m_memListElements[iii].pointerAllocated)) {
if (dataBase[jjj] == uint64_t(m_memListElements[iii].id)) {
find = true;
break;
}
@ -446,6 +448,17 @@ class memoryAllocatorHandle {
return haveError == false;
}
void flipID(void* _pointer1, void* _pointer2) {
MemoryElementSystem* handle1 = getAdressedElement((char*)_pointer1);
MemoryElementSystem* handle2 = getAdressedElement((char*)_pointer2);
if ( handle1 == nullptr
|| handle2 == nullptr) {
ETK_MEMORY_WARNING("MEM flip error %p %p", _pointer1, _pointer2);
return;
}
etk::swap(handle1->id, handle2->id);
}
void clearSnapshoot(uint64_t* _handle) {
if (_handle == nullptr) {
return;
@ -453,8 +466,6 @@ class memoryAllocatorHandle {
delete[] (uint64_t*)_handle;
}
void* allocate(size_t _num,
size_t _size,
const char* _variableName,
@ -469,32 +480,17 @@ class memoryAllocatorHandle {
if (myElement != nullptr) {
#if ETK_MEMORY_CHECKER > 1
const char *fileNameShort = nullptr;
myElement->id = m_dynamicID;
#endif
myElement->id = m_dynamicID;
// if an element is free :
myElement->sizeUser = _size * _num;
myElement->sizeData = _size;
#if ETK_MEMORY_CHECKER > 1
myElement->sizeAllocate = myElement->sizeUser + m_checkBorneSize*2;
if (_variableName == nullptr) {
strncpy(myElement->variableName, "---", ETK_MEM_MAX_STRING_SIZE);
} else {
strncpy(myElement->variableName, _variableName, ETK_MEM_MAX_STRING_SIZE);
}
myElement->variableName[ETK_MEM_MAX_STRING_SIZE-1] = 0;
if (_functionName == nullptr) {
strncpy(myElement->functionName, "---", ETK_MEM_MAX_STRING_SIZE);
} else {
strncpy(myElement->functionName, _functionName, ETK_MEM_MAX_STRING_SIZE);
}
myElement->functionName[ETK_MEM_MAX_STRING_SIZE-1] = 0;
if (_fileName == nullptr) {
strncpy(myElement->fileName, "---", ETK_MEM_MAX_STRING_SIZE);
} else {
fileNameShort = getFileName(_fileName);
strncpy(myElement->fileName, fileNameShort, ETK_MEM_MAX_STRING_SIZE);
}
myElement->fileName[ETK_MEM_MAX_STRING_SIZE-1] = 0;
myElement->variableName = _variableName;
myElement->functionName = _functionName;
myElement->fileName = _fileName;
//fileNameShort = getFileName(_fileName);
myElement->functionLine = _line;
#else
myElement->sizeAllocate = myElement->sizeUser;
@ -512,7 +508,7 @@ class memoryAllocatorHandle {
#else
myElement->pointerGiveToUser = myElement->pointerAllocated;
#endif
ETK_MEMORY_VERBOSE("MEM allocate (L): %s : %ld Bytes @ %p ==> user @ %p", _variableName, _num*_size, myElement->pointerAllocated, myElement->pointerGiveToUser);
ETK_MEMORY_VERBOSE("MEM allocate (L): %s : %ld Bytes @ %p ==> user @ %p id=%ld", _variableName, _num*_size, myElement->pointerAllocated, myElement->pointerGiveToUser, myElement->id);
// set bornes:
#if ETK_MEMORY_CHECKER > 1
memcpy(myElement->pointerAllocated, m_blockCheckMemory, m_checkBorneSize);
@ -523,7 +519,7 @@ class memoryAllocatorHandle {
// add to the elements list
myElement->used = true;
} else {
ETK_MEMORY_VERBOSE("MEM allocate (L): %s : %zu Bytes @ (ERROR)", _variableName, myElement->sizeUser);
ETK_MEMORY_VERBOSE("MEM allocate (L): %s : %ld Bytes @ (ERROR)", _variableName, uint64_t(myElement->sizeUser));
}
unLock();
// else : no memory allocated ==> nothing to save
@ -533,12 +529,20 @@ class memoryAllocatorHandle {
void * localPointer = nullptr;
localPointer = new char[_num * _size];
if (localPointer != nullptr) {
ETK_MEMORY_VERBOSE("MEM allocate (-): %s : %lu Bytes @ %p (No log...)", _variableName, _num*_size, localPointer);
if (_variableName == nullptr) {
ETK_MEMORY_VERBOSE("MEM allocate (-): --- : %lu Bytes @ %p (No log...)", _num*_size, localPointer);
} else {
ETK_MEMORY_VERBOSE("MEM allocate (-): %s : %lu Bytes @ %p (No log...)", _variableName, _num*_size, localPointer);
}
// set edded memory
//addMemory(_num * _size); // not availlable can not un add memory
m_totalMemAllocated += _num * _size;
} else {
ETK_MEMORY_VERBOSE("MEM allocate (-): %s : %lu Bytes @ (ERROR)", _variableName, _num*_size);
if (_variableName == nullptr) {
ETK_MEMORY_VERBOSE("MEM allocate (-): --- : %lu Bytes @ (ERROR)", _num*_size);
} else {
ETK_MEMORY_VERBOSE("MEM allocate (-): %s : %lu Bytes @ (ERROR)", _variableName, _num*_size);
}
}
unLock();
return localPointer;
@ -557,21 +561,37 @@ class memoryAllocatorHandle {
#if ETK_MEMORY_CHECKER > 1
// check end and Start :
if (checkMem(myElement->pointerAllocated) == true) {
ETK_MEMORY_ERROR("MEM free (L): %s : %zu Bytes @ %p ==> user @ %p (depassement pre)",_variableName, myElement->sizeUser, myElement->pointerAllocated, myElement->pointerGiveToUser);
if (_variableName == nullptr) {
ETK_MEMORY_ERROR("MEM free (L): --- : %ld Bytes @ %p ==> user @ %p (depassement pre)", uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
} else {
ETK_MEMORY_ERROR("MEM free (L): %s : %ld Bytes @ %p ==> user @ %p (depassement pre)", _variableName, uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
}
errorOccured = true;
}
if (checkMem(myElement->pointerAllocated + myElement->sizeUser + m_checkBorneSize) == true) {
ETK_MEMORY_ERROR("MEM free (L): %s : %zu Bytes @ %p ==> user @ %p (depassement post)",_variableName, myElement->sizeUser, myElement->pointerAllocated, myElement->pointerGiveToUser);
if (_variableName == nullptr) {
ETK_MEMORY_ERROR("MEM free (L): --- : %ld Bytes @ %p ==> user @ %p (depassement post)", uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
} else {
ETK_MEMORY_ERROR("MEM free (L): %s : %ld Bytes @ %p ==> user @ %p (depassement post)", _variableName, uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
}
errorOccured = true;
}
if (errorOccured == false) {
ETK_MEMORY_VERBOSE("MEM free (L): %s : %zu Bytes @ %p ==> user @ %p",_variableName, myElement->sizeUser, myElement->pointerAllocated, myElement->pointerGiveToUser);
if (_variableName == nullptr) {
ETK_MEMORY_VERBOSE("MEM free (L): --- : %ld Bytes @ %p ==> user @ %p", uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
} else {
ETK_MEMORY_VERBOSE("MEM free (L): %s : %ld Bytes @ %p ==> user @ %p", _variableName, uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
}
} else {
displayBuffer(myElement->pointerAllocated, myElement->sizeAllocate);
//ETK_ASSERT(1 == 0, "Memory error detected");
}
#else
ETK_MEMORY_VERBOSE("MEM free (L): %s : %d Bytes @ %p ==> user @ %p",_variableName, myElement->sizeUser, myElement->pointerAllocated, myElement->pointerGiveToUser);
if (_variableName == nullptr) {
ETK_MEMORY_VERBOSE("MEM free (L): --- : %ld Bytes @ %p ==> user @ %p", uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
} else {
ETK_MEMORY_VERBOSE("MEM free (L): %s : %ld Bytes @ %p ==> user @ %p", _variableName, uint64_t(myElement->sizeUser), myElement->pointerAllocated, myElement->pointerGiveToUser);
}
#endif
asyncFree = myElement->pointerAllocated;
myElement->pointerAllocated = nullptr;
@ -585,7 +605,20 @@ class memoryAllocatorHandle {
return;
}
//Unknown element
ETK_MEMORY_WARNING("MEM free (-): %s : ?? Bytes @ %p ==> unsaved element",_variableName, _pointerData);
if (_variableName == nullptr) {
ETK_MEMORY_WARNING("MEM free (-): --- : ?? Bytes @ %p ==> unsaved element", _pointerData);
} else {
ETK_MEMORY_WARNING("MEM free (-): %s : ?? Bytes @ %p ==> unsaved element", _variableName, _pointerData);
}
lock();
for (size_t iii=0; iii<m_memListElementSize; ++iii) {
if (m_memListElements[iii].used == false) {
if (m_memListElements[iii].pointerGiveToUser == _pointerData) {
ETK_MEMORY_ERROR("MEM free (D): --- : user @ %p (double 'free' detected)", m_memListElements[iii].pointerGiveToUser);
}
}
}
unLock();
delete (char*)_pointerData;
}
@ -654,11 +687,19 @@ class memoryAllocatorHandle {
#if ETK_MEMORY_CHECKER > 1
bool errorOccured = false;
if (checkMem(m_memListElements[iii].pointerAllocated) == true) {
ETK_MEMORY_ERROR("MEM CHECK (L): %s : %ld Bytes @ %p ==> user @ %p (depassement pre)",m_memListElements[iii].variableName, m_memListElements[iii].sizeUser, m_memListElements[iii].pointerAllocated, m_memListElements[iii].pointerGiveToUser);
const char* tmp = m_memListElements[iii].variableName;
if (tmp == nullptr) {
tmp = "---";
}
ETK_MEMORY_ERROR("MEM CHECK (L): %s : %ld Bytes @ %p ==> user @ %p (depassement pre)", tmp, uint64_t(m_memListElements[iii].sizeUser), m_memListElements[iii].pointerAllocated, m_memListElements[iii].pointerGiveToUser);
errorOccured = true;
}
if (checkMem(m_memListElements[iii].pointerAllocated + m_memListElements[iii].sizeUser + m_checkBorneSize) == true) {
ETK_MEMORY_ERROR("MEM CHECK (L): %s : %ld Bytes @ %p ==> user @ %p (depassement post)",m_memListElements[iii].variableName, m_memListElements[iii].sizeUser, m_memListElements[iii].pointerAllocated, m_memListElements[iii].pointerGiveToUser);
const char* tmp = m_memListElements[iii].variableName;
if (tmp == nullptr) {
tmp = "---";
}
ETK_MEMORY_ERROR("MEM CHECK (L): %s : %ld Bytes @ %p ==> user @ %p (depassement post)", tmp, uint64_t(m_memListElements[iii].sizeUser), m_memListElements[iii].pointerAllocated, m_memListElements[iii].pointerGiveToUser);
errorOccured = true;
}
if (errorOccured == true) {
@ -717,6 +758,10 @@ void etk::memory::clearSnapshoot(uint64_t* _handle) {
getHandle().clearSnapshoot(_handle);
}
void etk::memory::flipID(void* _pointer1, void* _pointer2) {
getHandle().flipID(_pointer1, _pointer2);
}
void* etk::memory::allocate(size_t _num,
size_t _size,
const char* _variableName,

View File

@ -17,13 +17,13 @@
}
#endif
#define ETK_MEMORY_CHECKER 2
//#define ETK_MEMORY_CHECKER 0
#ifndef ETK_MEMORY_CHECKER
#define ETK_MEMORY_CHECKER 0
#endif
#if ETK_MEMORY_CHECKER >= 0
#if ETK_MEMORY_CHECKER > 0
namespace etk {
namespace memory {
/**
@ -80,6 +80,10 @@
* @param[in] _handle Handle on the snapshoot
*/
void clearSnapshoot(uint64_t* _handle);
/**
* @brief When reallocate data and permit to the allocator to not warning when check the the snapshoot
*/
void flipID(void* _pointer1, void* _pointer2);
template<class ETK_TYPE,
class... ETK_MEMORY_ARGS>
@ -136,16 +140,22 @@
#define ETK_MEM_CHECK() \
etk::memory::check()
#define ETK_MEM_CHECK_POINTER(pointer) \
etk::memory::checkPointer(pointer)
#define ETK_MEM_FLIP_ID(pointer1, pointer2) \
etk::memory::flipID((void*)pointer1, (void*)pointer2)
#else
namespace etk {
namespace memory {
template<class ETK_TYPE,
class... T_ARGS>
ETK_TYPE* allocatorNew(T_ARGS&& ... _args) {
class... ETK_MEMORY_ARGS>
ETK_TYPE* allocatorNew(ETK_MEMORY_ARGS&& ... _args) {
return new ETK_TYPE(etk::forward<ETK_MEMORY_ARGS>(_args)...);
}
template<class ETK_TYPE,
class... T_ARGS>
class... ETK_MEMORY_ARGS>
ETK_TYPE* allocatorNewFull(const char* _variableName,
const char* _functionName,
int32_t _line,
@ -171,7 +181,7 @@
delete ((type*)(pointerData))
#define ETK_MALLOC(dataType, nbElements) \
((dataType *)new dataType[nbElements]
(dataType *)new dataType[nbElements]
#define ETK_FREE(type, pointerData) \
delete[] (type*)pointerData
@ -181,5 +191,11 @@
#define ETK_MEM_CHECK() \
do {} while(false)
#define ETK_MEM_CHECK_POINTER(pointer) \
do {} while(false)
#define ETK_MEM_FLIP_ID(pointer1, pointer2) \
do {} while(false)
#endif

View File

@ -31,6 +31,10 @@ namespace etk {
ETK_FUNCTION_DEBUG(" COPY NULLPTR \n");
return nullptr;
}
virtual void copyIn(char* _buffer) {
ETK_FUNCTION_DEBUG(" COPY NULLPTR \n");
return;
}
};
template <typename ETK_TYPE_FUNCTION_FUNCTOR, typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
class FunctionPrivateLambda<ETK_TYPE_FUNCTION_FUNCTOR, ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>:
@ -58,6 +62,11 @@ namespace etk {
ETK_FUNCTION_DEBUG(" COPY FunctionPrivateLambda \n");
return ETK_NEW(FunctionPrivateLambda, m_dataPointer);
}
virtual void copyIn(char* _buffer) {
ETK_FUNCTION_DEBUG(" COPY NULLPTR \n");
new (_buffer) FunctionPrivateLambda(m_dataPointer);
return;
}
};
template <typename ETK_TYPE_FUNCTION>
@ -69,29 +78,42 @@ namespace etk {
private:
typedef FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> FunctionPrivateTypedef;
FunctionPrivateTypedef* m_pointerPrivate;
bool m_local;
char m_buffer[16];
uint32_t m_pppppp;
public:
Function():
m_pointerPrivate(nullptr) {
m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 1 \n", m_pppppp, (uint64_t)this);
}
Function(const etk::NullPtr&):
m_pointerPrivate(nullptr) {
m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 2\n", m_pppppp, (uint64_t)this);
}
Function(const Function& _obj):
m_pointerPrivate(nullptr) {
m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function (copy constructor) ---------------------- [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
if (_obj.m_pointerPrivate != nullptr) {
if (_obj.m_local == true) {
((FunctionPrivateTypedef*)_obj.m_buffer)->copyIn(m_buffer);
m_local = true;
} else if (_obj.m_pointerPrivate != nullptr) {
m_pointerPrivate = _obj.m_pointerPrivate->copy();
}
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function (copy constructor) ------- (done) ------- [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
}
Function(Function&& _obj):
m_pointerPrivate(nullptr) {
m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d] create Function 2\n", m_pppppp);
_obj.swap(*this);
@ -103,33 +125,51 @@ namespace etk {
>::type = 0
>
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor):
m_pointerPrivate(nullptr) {
m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 4 \n", m_pppppp, (uint64_t)this);
typedef FunctionPrivateLambda<ETK_TYPE_FUNCTION_FUNCTOR, ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> FunctionPrivateLambdaTypedef;
m_pointerPrivate = ETK_NEW(FunctionPrivateLambdaTypedef, _functor);
if (sizeof(FunctionPrivateLambdaTypedef) <= sizeof(m_buffer)) {
new(m_buffer) FunctionPrivateLambdaTypedef(_functor);
m_local = true;
} else {
m_pointerPrivate = ETK_NEW(FunctionPrivateLambdaTypedef, _functor);
}
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 4 (done)\n", m_pppppp, (uint64_t)this);
}
~Function() {
ETK_FUNCTION_DEBUG("[%d=0X%lx] DELETE Function \n", m_pppppp, (uint64_t)this);
ETK_DELETE(FunctionPrivateTypedef, m_pointerPrivate);
m_pointerPrivate = nullptr;
if (m_local == true) {
// force the cast:
FunctionPrivateTypedef* tmp = (FunctionPrivateTypedef*)m_buffer;
tmp->~FunctionPrivate();
m_local = false;
memset(m_buffer, 0, sizeof(m_buffer));
}
}
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) const {
if (m_pointerPrivate == nullptr) {
if ( m_pointerPrivate == nullptr
&& m_local == false) {
ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function (With nullptr !!! ==> must assert ...)\n", m_pppppp, (uint64_t)this);
throw;
}
ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function \n", m_pppppp, (uint64_t)this);
if (m_local == true) {
return (*((FunctionPrivateTypedef*)m_buffer))(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
}
return (*m_pointerPrivate)(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
}
Function& operator= (const Function& _obj){
Function& operator= (const Function& _obj) {
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(set) Function [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
Function(_obj).swap(*this);
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(set) Function [%d=0X%lx] (done)\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
return *this;
}
Function& operator= (Function&& _obj){
Function& operator= (Function&& _obj) {
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(move) Function [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
Function(etk::move(_obj)).swap(*this);
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(move) Function [%d=0X%lx] (done)\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
@ -138,6 +178,13 @@ namespace etk {
Function& operator= (etk::NullPtr _obj) {
ETK_DELETE(FunctionPrivateTypedef, m_pointerPrivate);
m_pointerPrivate = nullptr;
if (m_local == true) {
// force the cast:
FunctionPrivateTypedef* tmp = (FunctionPrivateTypedef*)m_buffer;
tmp->~FunctionPrivate();
m_local = false;
memset(m_buffer, 0, sizeof(m_buffer));
}
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = nullptr 0X%lx\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate);
return *this;
}
@ -146,6 +193,13 @@ namespace etk {
ETK_FUNCTION_DEBUG("[%d=0X%lx] swap [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)_obj);
etk::swap(m_pointerPrivate, _obj.m_pointerPrivate);
etk::swap(m_pppppp, _obj.m_pppppp);
etk::swap(m_local, _obj.m_local);
// TODO : This is dangerous ==> to check ...
for (size_t iii=0; iii<sizeof(m_buffer); ++iii) {
char tmp = m_buffer[iii];
m_buffer[iii] = _obj.m_buffer[iii];
_obj.m_buffer[iii] = tmp;
}
ETK_FUNCTION_DEBUG("[%d=0X%lx] swap [%d=0X%lx] (done)\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)_obj);
}
template <typename ETK_TYPE_FUNCTION_FUNCTOR,
@ -171,19 +225,26 @@ namespace etk {
return *this;
}
operator bool() const {
return m_pointerPrivate != nullptr;
return m_pointerPrivate != nullptr
|| m_local == true ;
}
bool operator!= (etk::NullPtr) const {
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator != nullptr ==> 0X%lx %s\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate, (m_pointerPrivate != nullptr)?"true":"false");
return m_pointerPrivate != nullptr;
return m_pointerPrivate != nullptr
|| m_local == true;
}
bool operator== (etk::NullPtr) const {
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator == nullptr ==> 0X%lx %s\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate, (m_pointerPrivate == nullptr)?"true":"false");
return m_pointerPrivate == nullptr;
return m_pointerPrivate == nullptr
&& m_local == false;
}
etk::String toString() const {
etk::String out = "etk::Function<..(...)>(@";
out += etk::toString((uint64_t)m_pointerPrivate);
if (m_local == true) {
out += etk::toString((uint64_t)m_buffer);
} else {
out += etk::toString((uint64_t)m_pointerPrivate);
}
out += ")";
return out;
}

View File

@ -246,6 +246,7 @@ namespace etk {
typedef etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA> pairType;
etk::Vector<pairType*> m_data; //!< Data of the Map ==> the Map table is composed of pointer, this permit to have high speed when resize the vector ...
sortFunction m_comparator;
bool m_ordered;
public:
/**
* @brief Set the comparator of the set.
@ -253,29 +254,47 @@ namespace etk {
*/
void setComparator(sortFunction _comparator) {
m_comparator = _comparator;
sort();
}
/**
* @brief Set the ordering of the Map.
* @param[in] _ordered Order the map or not.
*/
void setOrdered(bool _ordered) {
m_ordered = _ordered;
sort();
}
private:
/**
* @brief Order the Set with the corect functor and if needed
*/
void sort() {
if (m_ordered == false) {
return;
}
if (m_comparator != nullptr) {
m_data.sort(0, m_data.size(), m_comparator);
} else {
m_data.sort(0, m_data.size(), [](etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA>* const & _key1,
etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA>* const & _key2) {
return _key1->first < _key2->first;
});
}
}
public:
/**
* @brief Constructor of the Map table.
* @param[in] _count Number of basic element in the table.
* @param[in] _ordered select an ordered map or an onordered map.
* @param[in] _comparator Comparator to use in comparing the elements;
*/
Map(size_t _count=0,
bool _ordered=true,
sortFunction _comparator = [](etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA>* const & _key1,
etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA>* const & _key2) {
return _key1->first < _key2->first;
}) :
Map(size_t _count = 0,
bool _ordered = true,
sortFunction _comparator = nullptr) :
m_data(),
m_comparator(etk::move(_comparator)) {
m_comparator(etk::move(_comparator)),
m_ordered(_ordered) {
m_data.reserve(_count);
if (_ordered == false) {
m_comparator = nullptr;
}
// nothing to do
}
/**
* @brief Move constructor
@ -283,7 +302,8 @@ namespace etk {
*/
Map(Map&& _obj):
m_data(),
m_comparator(nullptr) {
m_comparator(nullptr),
m_ordered(true) {
_obj.swap(*this);
}
/**
@ -292,7 +312,8 @@ namespace etk {
*/
Map(const Map& _obj) :
m_data(),
m_comparator(_obj.m_comparator) {
m_comparator(_obj.m_comparator),
m_ordered(_obj.m_ordered) {
m_data.reserve(_obj.m_data.size());
for (auto &it : _obj.m_data) {
if (it == nullptr) {
@ -301,19 +322,6 @@ namespace etk {
m_data.pushBack(ETK_NEW(pairType, it->first, it->second));
}
}
void setOrdered(bool _ordered) {
if (_ordered == false) {
m_comparator = nullptr;
} else {
m_comparator = [](etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA>* const & _key1,
etk::Pair<ETK_MAP_TYPE_KEY, ETK_MAP_TYPE_DATA>* const & _key2) {
return _key1->first < _key2->first;
};
}
if (m_comparator != nullptr) {
m_data.sort(0, m_data.size(), m_comparator);
}
}
/**
* @brief Destructor of the Map table (clear all element in the table)
*/
@ -327,6 +335,7 @@ namespace etk {
void swap(Map& _obj) {
etk::swap(m_data, _obj.m_data);
etk::swap(m_comparator, _obj.m_comparator);
etk::swap(m_ordered, _obj.m_ordered);
}
/**
* @brief Move operator
@ -364,7 +373,7 @@ namespace etk {
* @return Id of the element in the table or -1 of it does not existed
*/
int64_t getId(const ETK_MAP_TYPE_KEY& _key) const {
if (m_comparator != nullptr) {
if (m_ordered == true) {
// TODO: search in a dichotomic way.
}
for (size_t iii=0; iii<m_data.size(); iii++) {
@ -433,9 +442,7 @@ namespace etk {
}
m_data.pushBack(tmp);
// Order data if needed.
if (m_comparator != nullptr) {
m_data.sort(0, m_data.size(), m_comparator);
}
sort();
return;
}
m_data[elementId]->second = _value;
@ -587,8 +594,6 @@ namespace etk {
}
return 0;
}
};
}

View File

@ -190,7 +190,7 @@ class FindProperty {
public:
etk::Vector<FindProperty> m_subProperty; //!< list of all sub elements
public:
FindProperty() :
FindProperty():
m_positionStart(-1),
m_positionStop(-1),
m_multiplicity(0),
@ -198,12 +198,53 @@ class FindProperty {
m_subIndex(-1) {
// nothing to do ...
}
// move operator
FindProperty(FindProperty&& _obj):
m_positionStart(-1),
m_positionStop(-1),
m_multiplicity(0),
m_status(parseStatusUnknown),
m_subIndex(-1) {
swap(_obj);
}
// copy operator
FindProperty(const FindProperty& _obj):
m_positionStart(_obj.m_positionStart),
m_positionStop(_obj.m_positionStop),
m_multiplicity(_obj.m_multiplicity),
m_status(_obj.m_status),
m_subIndex(_obj.m_subIndex),
m_subProperty(_obj.m_subProperty) {
}
FindProperty& operator=(FindProperty&& _obj) {
swap(_obj);
return *this;
}
FindProperty& operator=(const FindProperty& _obj) {
m_positionStart = _obj.m_positionStart;
m_positionStop = _obj.m_positionStop;
m_multiplicity = _obj.m_multiplicity;
m_status = _obj.m_status;
m_subIndex = _obj.m_subIndex;
m_subProperty = _obj.m_subProperty;
return *this;
}
void swap(FindProperty& _obj) {
etk::swap(m_positionStart, _obj.m_positionStart);
etk::swap(m_positionStop, _obj.m_positionStop);
etk::swap(m_multiplicity, _obj.m_multiplicity);
etk::swap(m_status, _obj.m_status);
etk::swap(m_subIndex, _obj.m_subIndex);
etk::swap(m_subProperty, _obj.m_subProperty);
}
void reset() {
m_positionStart = -1;
m_positionStop = -1;
m_multiplicity = 0;
m_status = parseStatusUnknown;
m_subIndex = -1;
m_subProperty.clear();
}
int64_t getPositionStart() const {
return m_positionStart;
@ -305,6 +346,58 @@ template<class CLASS_TYPE> class Node {
* @brief Destructor
*/
virtual ~Node() { };
// move operator
Node(Node&& _obj) :
m_regExData(),
m_nodeLevel(0),
m_canHaveMultiplicity(true),
m_multipleMin(1),
m_multipleMax(1),
m_countOutput(true) {
swapData(&_obj);
}
// copy operator
Node(const Node& _obj) :
m_regExData(_obj.m_regExData),
m_nodeLevel(_obj.m_nodeLevel),
m_canHaveMultiplicity(_obj.m_canHaveMultiplicity),
m_multipleMin(_obj.m_multipleMin),
m_multipleMax(_obj.m_multipleMax),
m_countOutput(_obj.m_countOutput) {
}
Node& operator=(Node&& _obj) {
if(this != &_obj) {
swapData(&_obj);
}
return *this;
}
Node& operator=(const Node& _obj) {
copyData(&_obj);
return *this;
}
void swap(Node& _obj) {
swapData(&_obj);
}
virtual Node* clone() const = 0;
protected:
void swapData(Node* _obj) {
etk::swap(m_regExData, _obj->m_regExData);
etk::swap(m_nodeLevel, _obj->m_nodeLevel);
etk::swap(m_canHaveMultiplicity, _obj->m_canHaveMultiplicity);
etk::swap(m_multipleMin, _obj->m_multipleMin);
etk::swap(m_multipleMax, _obj->m_multipleMax);
etk::swap(m_countOutput, _obj->m_countOutput);
}
void copyData(const Node* _obj) {
m_regExData = _obj->m_regExData;
m_nodeLevel = _obj->m_nodeLevel;
m_canHaveMultiplicity = _obj->m_canHaveMultiplicity;
m_multipleMin = _obj->m_multipleMin;
m_multipleMax = _obj->m_multipleMax;
m_countOutput = _obj->m_countOutput;
}
public:
/**
* @brief Generate the regular expression with the current "converted string"
* @param[in] _data Property of the regex
@ -410,7 +503,6 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
// SubNodes :
etk::Vector<char32_t> m_data;
public :
/**
* @brief Constructor
*/
@ -419,7 +511,39 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
generate(_data);
};
int32_t generate(const etk::Vector<char32_t>& _data) {
// move operator
NodeValue(NodeValue&& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
Node<CLASS_TYPE>::swapData(&_obj);
etk::swap(m_data, _obj.m_data);
}
// copy operator
NodeValue(const NodeValue& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel),
m_data(_obj.m_data) {
Node<CLASS_TYPE>::copyData(&_obj);
}
NodeValue& operator=(NodeValue&& _obj) {
if(this != &_obj) {
Node<CLASS_TYPE>::swapData(&_obj);;
etk::swap(m_data, _obj.m_data);
}
// Return the current pointer
return *this;
}
NodeValue& operator=(const NodeValue& _obj) {
Node<CLASS_TYPE>::copyData(&_obj);
m_data = _obj.m_data;
return *this;
}
void swap(NodeValue& _obj) {
Node<CLASS_TYPE>::swapData(&_obj);
etk::swap(m_data, _obj.m_data);
}
Node<CLASS_TYPE>* clone() const override {
return ETK_NEW(NodeValue<CLASS_TYPE>, *this);
}
int32_t generate(const etk::Vector<char32_t>& _data) override {
Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse \"Value\" data=" << createString(Node<CLASS_TYPE>::m_regExData) );
m_data.clear();
@ -428,7 +552,7 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
}
return _data.size();
};
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) {
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) override {
TK_REG_DEBUG("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " Value{" << Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMax << "} : " << (char)m_data[0]);
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << createString(Node<CLASS_TYPE>::m_regExData));
TK_REG_DEBUG_3(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " Value " << _property);
@ -490,7 +614,7 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
return;
};
void display() {
void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@Value@ {"
<< Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << "} under-data="
@ -522,6 +646,51 @@ template<class CLASS_TYPE> class NodeRangeValue : public Node<CLASS_TYPE> {
* @brief Destructor
*/
virtual ~NodeRangeValue() { };
// move operator
NodeRangeValue(NodeRangeValue&& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel),
m_invert(false),
m_typeName("auto-range") {
swapRange(_obj);
}
// copy operator
NodeRangeValue(const NodeRangeValue& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
copyRange(&_obj);
}
NodeRangeValue& operator=(NodeRangeValue&& _obj) {
if(this != &_obj) {
swapRange(&_obj);
}
return *this;
}
NodeRangeValue& operator=(const NodeRangeValue& _obj) {
copyRange(_obj);
return *this;
}
void swap(NodeRangeValue& _obj) {
swapRange(&_obj);
}
Node<CLASS_TYPE>* clone() const override {
return ETK_NEW(NodeRangeValue<CLASS_TYPE>, *this);
}
protected:
void swapRange(NodeRangeValue* _obj) {
Node<CLASS_TYPE>::swapData(_obj);
etk::swap(m_rangeList, _obj->m_rangeList);
etk::swap(m_dataList, _obj->m_dataList);
etk::swap(m_invert, _obj->m_invert);
etk::swap(m_typeName, _obj->m_typeName);
}
void copyRange(const NodeRangeValue* _obj) {
Node<CLASS_TYPE>::copyData(_obj);
m_rangeList = _obj->m_rangeList;
m_dataList = _obj->m_dataList;
m_invert = _obj->m_invert;
m_typeName = _obj->m_typeName;
}
public:
void addRange(char32_t _start, char32_t _stop) {
m_rangeList.pushBack(etk::makePair(_start, _stop));
}
@ -538,7 +707,7 @@ template<class CLASS_TYPE> class NodeRangeValue : public Node<CLASS_TYPE> {
m_typeName = _name;
}
// TODO: multiplicity minimum, return partial, and ...
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) {
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) override {
int32_t findLen = 0;
TK_REG_DEBUG("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << getDescriptiveName() << "{" << Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMax << "}");
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << createString(Node<CLASS_TYPE>::m_regExData));
@ -630,7 +799,7 @@ template<class CLASS_TYPE> class NodeRangeValue : public Node<CLASS_TYPE> {
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << getDescriptiveName() << " : out=" << _property);
return;
};
virtual void display() {
virtual void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << getDescriptiveName() << " {"
<< Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax <<
@ -652,7 +821,34 @@ template<class CLASS_TYPE> class NodeBracket : public NodeRangeValue<CLASS_TYPE>
NodeBracket(const etk::Vector<char32_t>& _data, int32_t _level) : NodeRangeValue<CLASS_TYPE>::NodeRangeValue(_level) {
generate(_data);
};
int32_t generate(const etk::Vector<char32_t>& _data) {
// move operator
NodeBracket(NodeBracket&& _obj):
NodeRangeValue<CLASS_TYPE>::NodeRangeValue(_obj.m_nodeLevel) {
NodeRangeValue<CLASS_TYPE>::swapRange(&_obj);
}
// copy operator
NodeBracket(const NodeBracket& _obj):
NodeRangeValue<CLASS_TYPE>::NodeRangeValue(_obj.m_nodeLevel) {
NodeRangeValue<CLASS_TYPE>::copyRange(&_obj);
}
NodeBracket& operator=(NodeBracket&& _obj) {
if(this != &_obj) {
NodeRangeValue<CLASS_TYPE>::swapRange(&_obj);
}
// Return the current pointer
return *this;
}
NodeBracket& operator=(const NodeBracket& _obj) {
NodeRangeValue<CLASS_TYPE>::copyRange(&_obj);
return *this;
}
void swap(NodeBracket& _obj) {
NodeRangeValue<CLASS_TYPE>::swapRange(&_obj);
}
Node<CLASS_TYPE>* clone() const override {
return ETK_NEW(NodeBracket<CLASS_TYPE>, *this);
}
int32_t generate(const etk::Vector<char32_t>& _data) override {
Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse [...] data=" << createString(Node<CLASS_TYPE>::m_regExData) );
@ -720,7 +916,34 @@ template<class CLASS_TYPE> class NodeSOL : public Node<CLASS_TYPE> {
* @brief Destructor
*/
~NodeSOL() { };
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) {
// move operator
NodeSOL(NodeSOL&& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
Node<CLASS_TYPE>::swapData(&_obj);
}
// copy operator
NodeSOL(const NodeSOL& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
Node<CLASS_TYPE>::copyData(&_obj);
}
NodeSOL& operator=(NodeSOL&& _obj) {
if(this != &_obj) {
Node<CLASS_TYPE>::swapData(&_obj);
}
// Return the current pointer
return *this;
}
NodeSOL& operator=(const NodeSOL& _obj) {
Node<CLASS_TYPE>::copyData(&_obj);
return *this;
}
void swap(NodeSOL& _obj) {
Node<CLASS_TYPE>::swapData(&_obj);
}
Node<CLASS_TYPE>* clone() const override {
return ETK_NEW(NodeSOL<CLASS_TYPE>, *this);
}
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) override {
int32_t findLen = 0;
bool tmpFind = false;
TK_REG_DEBUG("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " SOL{" << Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMax << "}");
@ -754,7 +977,7 @@ template<class CLASS_TYPE> class NodeSOL : public Node<CLASS_TYPE> {
_property.setStatus(parseStatusNone);
return;
};
void display() {
void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@SOL@ {"
<< Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << "} under-data="
@ -782,23 +1005,73 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
/**
* @brief Constructor
*/
NodePTheseElement(int32_t _level) : Node<CLASS_TYPE>::Node(_level) { };
NodePTheseElement(const etk::Vector<char32_t>& _data, int32_t _level) : Node<CLASS_TYPE>::Node(_level) {
NodePTheseElement(int32_t _level):
Node<CLASS_TYPE>::Node(_level) {
}
NodePTheseElement(const etk::Vector<char32_t>& _data, int32_t _level):
Node<CLASS_TYPE>::Node(_level) {
generate(_data);
};
}
// move operator
NodePTheseElement(NodePTheseElement&& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
swapData(&_obj);
etk::swap(m_subNode, _obj.m_nodeLevel);
}
// copy operator
NodePTheseElement(const NodePTheseElement& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
Node<CLASS_TYPE>::copyData(&_obj);
// Force a specicfic size
m_subNode.reserve(_obj.m_subNode.size());
for(size_t iii=0; iii<_obj.m_subNode.size(); iii++) {
if (_obj.m_subNode[iii] != nullptr) {
m_subNode.pushBack(_obj.m_subNode[iii]->clone());
}
}
}
NodePTheseElement& operator=(NodePTheseElement&& _obj) {
if(this != &_obj) {
swapData(&_obj);
etk::swap(m_subNode, _obj.m_subNode);
}
return *this;
}
NodePTheseElement& operator=(const NodePTheseElement& _obj) {
Node<CLASS_TYPE>::copyData(&_obj);
for (auto it : m_subNode) {
ETK_DELETE(Node<CLASS_TYPE>, it);
it = nullptr;
}
m_subNode.clear();
// Force a specicfic size
m_subNode.reserve(_obj.m_subNode.size());
for(size_t iii=0; iii<_obj.m_subNode.size(); iii++) {
if (_obj.m_subNode[iii] != nullptr) {
m_subNode.pushBack(_obj.m_subNode[iii]->clone());
}
}
return *this;
}
void swap(NodePTheseElement& _obj) {
swapData(&_obj);
etk::swap(m_subNode, _obj.m_subNode);
}
Node<CLASS_TYPE>* clone() const override {
return ETK_NEW(NodePTheseElement<CLASS_TYPE>, *this);
}
/**
* @brief Destructor
*/
~NodePTheseElement() {
/*
for (auto it : m_subNode) {
ETK_DELETE(Node<CLASS_TYPE>, *it);
*it = nullptr;
ETK_DELETE(Node<CLASS_TYPE>, it);
it = nullptr;
}
*/
m_subNode.clear();
};
int32_t generate(const etk::Vector<char32_t>& _data) {
int32_t generate(const etk::Vector<char32_t>& _data) override {
Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse (element) data=" << createString(Node<CLASS_TYPE>::m_regExData) );
int64_t pos = 0;
@ -997,7 +1270,7 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
}
return _data.size();
};
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) {
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) override {
//TK_REG_DEBUG_2("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " (element) data to parse : '" << autoStr(etk::String(_data, _currentPos, _lenMax-_currentPos)) << "'");
//TK_REG_DEBUG_2("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " (element) m_data='" << autoStr(Node<CLASS_TYPE>::m_data) << "'");
TK_REG_DEBUG("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " (element) " << _property);
@ -1096,7 +1369,7 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " (element) return=" << _property);
}
void display() {
void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@(Element)@ {"
<< Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << "} under-data="
@ -1105,7 +1378,7 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
it->display();
}
};
private :
private:
/**
* @brief Set the number of repeat time on a the last node in the list ...
* @param[in] _min Minimum of the multiplicity
@ -1140,15 +1413,61 @@ template<class CLASS_TYPE> class NodePThese : public Node<CLASS_TYPE> {
* @brief Destructor
*/
~NodePThese() {
/*
for (auto it : m_subNode) {
ETK_DELETE(Node<CLASS_TYPE>, *it);
*it = nullptr;
ETK_DELETE(Node<CLASS_TYPE>, it);
it = nullptr;
}
*/
m_subNode.clear();
}
int32_t generate(const etk::Vector<char32_t>& _data) {
// move operator
NodePThese(NodePThese&& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
Node<CLASS_TYPE>::swapData(&_obj);
etk::swap(m_subNode, _obj.m_subNode);
}
// copy operator
NodePThese(const NodePThese& _obj):
Node<CLASS_TYPE>::Node(_obj.m_nodeLevel) {
Node<CLASS_TYPE>::copyData(&_obj);
// Force a specicfic size
m_subNode.reserve(_obj.m_subNode.size());
for(size_t iii=0; iii<_obj.m_subNode.size(); iii++) {
if (_obj.m_subNode[iii] != nullptr) {
m_subNode.pushBack(_obj.m_subNode[iii]->clone());
}
}
}
NodePThese& operator=(NodePThese&& _obj) {
if(this != &_obj) {
Node<CLASS_TYPE>::swapData(&_obj);
etk::swap(m_subNode, _obj.m_subNode);
}
return *this;
}
NodePThese& operator=(const NodePThese& _obj) {
Node<CLASS_TYPE>::copyData(&_obj);
for (auto it : m_subNode) {
ETK_DELETE(Node<CLASS_TYPE>, it);
it = nullptr;
}
m_subNode.clear();
// Force a specicfic size
m_subNode.reserve(_obj.m_subNode.size());
for(size_t iii=0; iii<_obj.m_subNode.size(); iii++) {
if (_obj.m_subNode[iii] != nullptr) {
m_subNode.pushBack(_obj.m_subNode[iii]->clone());
}
}
return *this;
}
void swap(NodePThese& _obj) {
Node<CLASS_TYPE>::swapData(&_obj);
etk::swap(m_subNode, _obj.m_subNode);
}
Node<CLASS_TYPE>* clone() const override {
return ETK_NEW(NodePThese<CLASS_TYPE>, *this);
}
int32_t generate(const etk::Vector<char32_t>& _data) override {
Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse (...) data=" << createString(Node<CLASS_TYPE>::m_regExData) );
//Find all the '|' in the string (and at the good level ...)
@ -1175,7 +1494,7 @@ template<class CLASS_TYPE> class NodePThese : public Node<CLASS_TYPE> {
}
return _data.size();
};
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) {
virtual void parse(const CLASS_TYPE& _data, int64_t _currentPos, int64_t _lenMax, FindProperty& _property) override {
TK_REG_DEBUG("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " (...) {" << Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMax << "}");
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " work on: " << createString(Node<CLASS_TYPE>::m_regExData));
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " pos=" << _currentPos << " ==> " << _lenMax);
@ -1314,7 +1633,7 @@ template<class CLASS_TYPE> class NodePThese : public Node<CLASS_TYPE> {
return;
};
void display() {
void display() override {
if (9999 <= Node<CLASS_TYPE>::m_nodeLevel) {
TK_INFO("regEx :" << createString(Node<CLASS_TYPE>::m_regExData) );
} else {
@ -1426,6 +1745,71 @@ template<class CLASS_TYPE> class RegEx {
m_isOk = false;
};
// move operator
RegEx(RegEx&& _obj) :
m_expressionRequested(U""),
m_isOk(false),
m_notBeginWithChar(false),
m_notEndWithChar(false),
m_maximize(false) {
etk::swap(*this, _obj);
etk::UString m_expressionRequested; //!< Regular expression parsed ...
regex::ElementPos m_areaFind; //!< position around selection
regex::NodePThese<CLASS_TYPE> m_expressionRootNode; //!< The tree where data is set
bool m_isOk; //!< Known if we can process with this regEx
bool m_notBeginWithChar; //!< The regular expression must not have previously a char [a-zA-Z0-9_]
bool m_notEndWithChar; //!< The regular expression must not have after the end a char [a-zA-Z0-9_]
bool m_maximize; //!< by default the regex find the minimum size of a regex .
OptionList m_options; //!< Global option list of the reg-ex.
}
// copy operator
RegEx(const RegEx& _obj) :
m_expressionRequested(_obj.m_expressionRequested),
m_areaFind(_obj.m_areaFind),
m_expressionRootNode(_obj.m_expressionRootNode),
m_isOk(_obj.m_isOk),
m_notBeginWithChar(_obj.m_notBeginWithChar),
m_notEndWithChar(_obj.m_notEndWithChar),
m_maximize(_obj.m_maximize),
m_options(_obj.m_options) {
}
RegEx& operator=(RegEx&& _obj) {
if(this != &_obj) {
etk::swap(m_expressionRequested, _obj.m_expressionRequested);
etk::swap(m_areaFind, _obj.m_areaFind);
etk::swap(m_expressionRootNode, _obj.m_expressionRootNode);
etk::swap(m_isOk, _obj.m_isOk);
etk::swap(m_notBeginWithChar, _obj.m_notBeginWithChar);
etk::swap(m_notEndWithChar, _obj.m_notEndWithChar);
etk::swap(m_maximize, _obj.m_maximize);
etk::swap(m_options, _obj.m_options);
}
return *this;
}
RegEx& operator=(const RegEx& _obj) {
m_expressionRequested = _obj.m_expressionRequested;
m_areaFind = _obj.m_areaFind;
m_expressionRootNode = _obj.m_expressionRootNode;
m_isOk = _obj.m_isOk;
m_notBeginWithChar = _obj.m_notBeginWithChar;
m_notEndWithChar = _obj.m_notEndWithChar;
m_maximize = _obj.m_maximize;
m_options = _obj.m_options;
return *this;
}
void swap(RegEx& _obj) {
etk::swap(m_expressionRequested, _obj.m_expressionRequested);
etk::swap(m_areaFind, _obj.m_areaFind);
etk::swap(m_expressionRootNode, _obj.m_expressionRootNode);
etk::swap(m_isOk, _obj.m_isOk);
etk::swap(m_notBeginWithChar, _obj.m_notBeginWithChar);
etk::swap(m_notEndWithChar, _obj.m_notEndWithChar);
etk::swap(m_maximize, _obj.m_maximize);
etk::swap(m_options, _obj.m_options);
}
/**
* @brief SetMaximizing of the regex
* @param[in] _value Maximize or not the regEx
@ -1977,4 +2361,4 @@ template<class CLASS_TYPE> class RegEx {
};
}; // end of etk namespace
}

View File

@ -233,17 +233,27 @@ namespace etk {
*/
void setComparator(sortFunction _comparator) {
m_comparator = _comparator;
sort();
}
private:
/**
* @brief Order the Set with the corect functor
*/
void sort() {
if (m_comparator != nullptr) {
m_data.sort(0, m_data.size(), m_comparator);
} else {
m_data.sort(0, m_data.size(), [](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; });
}
}
public:
/**
* @brief Constructor of the Set table.
* @param[in] _count Number of basic element (pre-allocated) in the table.
*/
Set(int32_t _count = 0) :
m_data(),
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) {
m_comparator(nullptr) {
m_data.reserve(_count);
// nothing to do
}
@ -255,7 +265,7 @@ namespace etk {
template<typename... ETK_SET_TYPE_2>
Set(const ETK_SET_TYPE_2& ... _args):
m_data(),
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) {
m_comparator(nullptr) {
add(_args...);
}
@ -337,6 +347,17 @@ namespace etk {
return;
}
}
} else {
for (size_t iii=0; iii<m_data.size(); ++iii) {
if (_key == m_data[iii]) {
return;
}
if (_key < m_data[iii]) {
// Find a position
m_data.insert(iii, etk::move(_key));
return;
}
}
}
m_data.pushBack(etk::move(_key));
}

View File

@ -845,6 +845,7 @@ namespace etk {
//TK_CRITICAL("Vector : Error in data allocation request allocation:" << requestSize << "*" << (int32_t)(sizeof(ETK_VECTOR_TYPE)) << "bytes" );
return;
}
ETK_MEM_FLIP_ID(dataTmp, m_data);
#ifdef DEBUG
// we place bad data to permit to detect stipid thing that is done in C++ code when developement is in progress.
// Only in debug this is really slow ... and for the real allocation of memory

View File

@ -18,5 +18,6 @@
int main(int argc, const char *argv[]) {
// init test engine:
etest::init(argc, argv);
TEST_INFO("TEST ETK");
return RUN_ALL_TESTS();
}