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

View File

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

View File

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

View File

@ -31,6 +31,10 @@ namespace etk {
ETK_FUNCTION_DEBUG(" COPY NULLPTR \n"); ETK_FUNCTION_DEBUG(" COPY NULLPTR \n");
return nullptr; 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> 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...)>: 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"); ETK_FUNCTION_DEBUG(" COPY FunctionPrivateLambda \n");
return ETK_NEW(FunctionPrivateLambda, m_dataPointer); 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> template <typename ETK_TYPE_FUNCTION>
@ -69,29 +78,42 @@ namespace etk {
private: private:
typedef FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> FunctionPrivateTypedef; typedef FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> FunctionPrivateTypedef;
FunctionPrivateTypedef* m_pointerPrivate; FunctionPrivateTypedef* m_pointerPrivate;
bool m_local;
char m_buffer[16];
uint32_t m_pppppp; uint32_t m_pppppp;
public: public:
Function(): Function():
m_pointerPrivate(nullptr) { m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++; m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 1 \n", m_pppppp, (uint64_t)this); ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 1 \n", m_pppppp, (uint64_t)this);
} }
Function(const etk::NullPtr&): Function(const etk::NullPtr&):
m_pointerPrivate(nullptr) { m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++; m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 2\n", m_pppppp, (uint64_t)this); ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 2\n", m_pppppp, (uint64_t)this);
} }
Function(const Function& _obj): Function(const Function& _obj):
m_pointerPrivate(nullptr) { m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++; 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); 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(); 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); 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): Function(Function&& _obj):
m_pointerPrivate(nullptr) { m_pointerPrivate(nullptr),
m_local(false) {
memset(m_buffer, 0, sizeof(m_buffer));
m_pppppp = MM___pppppp++; m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d] create Function 2\n", m_pppppp); ETK_FUNCTION_DEBUG("[%d] create Function 2\n", m_pppppp);
_obj.swap(*this); _obj.swap(*this);
@ -103,33 +125,51 @@ namespace etk {
>::type = 0 >::type = 0
> >
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor): 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++; m_pppppp = MM___pppppp++;
ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 4 \n", m_pppppp, (uint64_t)this); 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; 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); ETK_FUNCTION_DEBUG("[%d=0X%lx] create Function 4 (done)\n", m_pppppp, (uint64_t)this);
} }
~Function() { ~Function() {
ETK_FUNCTION_DEBUG("[%d=0X%lx] DELETE Function \n", m_pppppp, (uint64_t)this); ETK_FUNCTION_DEBUG("[%d=0X%lx] DELETE Function \n", m_pppppp, (uint64_t)this);
ETK_DELETE(FunctionPrivateTypedef, m_pointerPrivate); ETK_DELETE(FunctionPrivateTypedef, m_pointerPrivate);
m_pointerPrivate = nullptr; 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 { 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); ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function (With nullptr !!! ==> must assert ...)\n", m_pppppp, (uint64_t)this);
throw; throw;
} }
ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function \n", m_pppppp, (uint64_t)this); 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)...); 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); 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); 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); 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; 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); 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); 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); 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) { Function& operator= (etk::NullPtr _obj) {
ETK_DELETE(FunctionPrivateTypedef, m_pointerPrivate); ETK_DELETE(FunctionPrivateTypedef, m_pointerPrivate);
m_pointerPrivate = nullptr; 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); ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = nullptr 0X%lx\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate);
return *this; 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_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_pointerPrivate, _obj.m_pointerPrivate);
etk::swap(m_pppppp, _obj.m_pppppp); 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); 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, template <typename ETK_TYPE_FUNCTION_FUNCTOR,
@ -171,19 +225,26 @@ namespace etk {
return *this; return *this;
} }
operator bool() const { operator bool() const {
return m_pointerPrivate != nullptr; return m_pointerPrivate != nullptr
|| m_local == true ;
} }
bool operator!= (etk::NullPtr) const { 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"); 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 { 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"); 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 toString() const {
etk::String out = "etk::Function<..(...)>(@"; 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 += ")"; out += ")";
return out; return out;
} }

View File

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

View File

@ -190,7 +190,7 @@ class FindProperty {
public: public:
etk::Vector<FindProperty> m_subProperty; //!< list of all sub elements etk::Vector<FindProperty> m_subProperty; //!< list of all sub elements
public: public:
FindProperty() : FindProperty():
m_positionStart(-1), m_positionStart(-1),
m_positionStop(-1), m_positionStop(-1),
m_multiplicity(0), m_multiplicity(0),
@ -198,12 +198,53 @@ class FindProperty {
m_subIndex(-1) { m_subIndex(-1) {
// nothing to do ... // 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() { void reset() {
m_positionStart = -1; m_positionStart = -1;
m_positionStop = -1; m_positionStop = -1;
m_multiplicity = 0; m_multiplicity = 0;
m_status = parseStatusUnknown; m_status = parseStatusUnknown;
m_subIndex = -1; m_subIndex = -1;
m_subProperty.clear();
} }
int64_t getPositionStart() const { int64_t getPositionStart() const {
return m_positionStart; return m_positionStart;
@ -305,6 +346,58 @@ template<class CLASS_TYPE> class Node {
* @brief Destructor * @brief Destructor
*/ */
virtual ~Node() { }; 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" * @brief Generate the regular expression with the current "converted string"
* @param[in] _data Property of the regex * @param[in] _data Property of the regex
@ -410,7 +503,6 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
// SubNodes : // SubNodes :
etk::Vector<char32_t> m_data; etk::Vector<char32_t> m_data;
public : public :
/** /**
* @brief Constructor * @brief Constructor
*/ */
@ -419,7 +511,39 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
generate(_data); 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; Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse \"Value\" data=" << createString(Node<CLASS_TYPE>::m_regExData) ); TK_REG_DEBUG("Request Parse \"Value\" data=" << createString(Node<CLASS_TYPE>::m_regExData) );
m_data.clear(); m_data.clear();
@ -428,7 +552,7 @@ template<class CLASS_TYPE> class NodeValue : public Node<CLASS_TYPE> {
} }
return _data.size(); 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("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(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << createString(Node<CLASS_TYPE>::m_regExData));
TK_REG_DEBUG_3(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " Value " << _property); 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; return;
}; };
void display() { void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@Value@ {" TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@Value@ {"
<< Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << "} under-data=" << Node<CLASS_TYPE>::m_multipleMax << "} under-data="
@ -522,6 +646,51 @@ template<class CLASS_TYPE> class NodeRangeValue : public Node<CLASS_TYPE> {
* @brief Destructor * @brief Destructor
*/ */
virtual ~NodeRangeValue() { }; 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) { void addRange(char32_t _start, char32_t _stop) {
m_rangeList.pushBack(etk::makePair(_start, _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; m_typeName = _name;
} }
// TODO: multiplicity minimum, return partial, and ... // 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; 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("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)); 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); TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << getDescriptiveName() << " : out=" << _property);
return; return;
}; };
virtual void display() { virtual void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << getDescriptiveName() << " {" TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " " << getDescriptiveName() << " {"
<< Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << << 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) { NodeBracket(const etk::Vector<char32_t>& _data, int32_t _level) : NodeRangeValue<CLASS_TYPE>::NodeRangeValue(_level) {
generate(_data); 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; Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse [...] data=" << createString(Node<CLASS_TYPE>::m_regExData) ); 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 * @brief Destructor
*/ */
~NodeSOL() { }; ~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; int32_t findLen = 0;
bool tmpFind = false; bool tmpFind = false;
TK_REG_DEBUG("Parse " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " SOL{" << Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMax << "}"); 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); _property.setStatus(parseStatusNone);
return; return;
}; };
void display() { void display() override {
TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@SOL@ {" TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@SOL@ {"
<< Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << "} under-data=" << Node<CLASS_TYPE>::m_multipleMax << "} under-data="
@ -782,23 +1005,73 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
/** /**
* @brief Constructor * @brief Constructor
*/ */
NodePTheseElement(int32_t _level) : Node<CLASS_TYPE>::Node(_level) { }; NodePTheseElement(int32_t _level):
NodePTheseElement(const etk::Vector<char32_t>& _data, int32_t _level) : Node<CLASS_TYPE>::Node(_level) { Node<CLASS_TYPE>::Node(_level) {
}
NodePTheseElement(const etk::Vector<char32_t>& _data, int32_t _level):
Node<CLASS_TYPE>::Node(_level) {
generate(_data); 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 * @brief Destructor
*/ */
~NodePTheseElement() { ~NodePTheseElement() {
/*
for (auto it : m_subNode) { for (auto it : m_subNode) {
ETK_DELETE(Node<CLASS_TYPE>, *it); ETK_DELETE(Node<CLASS_TYPE>, it);
*it = nullptr; it = nullptr;
} }
*/
m_subNode.clear(); 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; Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse (element) data=" << createString(Node<CLASS_TYPE>::m_regExData) ); TK_REG_DEBUG("Request Parse (element) data=" << createString(Node<CLASS_TYPE>::m_regExData) );
int64_t pos = 0; int64_t pos = 0;
@ -997,7 +1270,7 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
} }
return _data.size(); 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) 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_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); 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); 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)@ {" TK_INFO("Find NODE : " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << "@(Element)@ {"
<< Node<CLASS_TYPE>::m_multipleMin << "," << Node<CLASS_TYPE>::m_multipleMin << ","
<< Node<CLASS_TYPE>::m_multipleMax << "} under-data=" << Node<CLASS_TYPE>::m_multipleMax << "} under-data="
@ -1105,7 +1378,7 @@ template<class CLASS_TYPE> class NodePTheseElement : public Node<CLASS_TYPE> {
it->display(); it->display();
} }
}; };
private : private:
/** /**
* @brief Set the number of repeat time on a the last node in the list ... * @brief Set the number of repeat time on a the last node in the list ...
* @param[in] _min Minimum of the multiplicity * @param[in] _min Minimum of the multiplicity
@ -1140,15 +1413,61 @@ template<class CLASS_TYPE> class NodePThese : public Node<CLASS_TYPE> {
* @brief Destructor * @brief Destructor
*/ */
~NodePThese() { ~NodePThese() {
/*
for (auto it : m_subNode) { for (auto it : m_subNode) {
ETK_DELETE(Node<CLASS_TYPE>, *it); ETK_DELETE(Node<CLASS_TYPE>, it);
*it = nullptr; it = nullptr;
} }
*/
m_subNode.clear(); 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; Node<CLASS_TYPE>::m_regExData = _data;
TK_REG_DEBUG("Request Parse (...) data=" << createString(Node<CLASS_TYPE>::m_regExData) ); TK_REG_DEBUG("Request Parse (...) data=" << createString(Node<CLASS_TYPE>::m_regExData) );
//Find all the '|' in the string (and at the good level ...) //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(); 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("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) << " work on: " << createString(Node<CLASS_TYPE>::m_regExData));
TK_REG_DEBUG(" " << levelSpace(Node<CLASS_TYPE>::m_nodeLevel) << " pos=" << _currentPos << " ==> " << _lenMax); 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; return;
}; };
void display() { void display() override {
if (9999 <= Node<CLASS_TYPE>::m_nodeLevel) { if (9999 <= Node<CLASS_TYPE>::m_nodeLevel) {
TK_INFO("regEx :" << createString(Node<CLASS_TYPE>::m_regExData) ); TK_INFO("regEx :" << createString(Node<CLASS_TYPE>::m_regExData) );
} else { } else {
@ -1426,6 +1745,71 @@ template<class CLASS_TYPE> class RegEx {
m_isOk = false; 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 * @brief SetMaximizing of the regex
* @param[in] _value Maximize or not 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) { void setComparator(sortFunction _comparator) {
m_comparator = _comparator; m_comparator = _comparator;
sort();
}
private:
/**
* @brief Order the Set with the corect functor
*/
void sort() {
if (m_comparator != nullptr) { if (m_comparator != nullptr) {
m_data.sort(0, m_data.size(), m_comparator); 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. * @brief Constructor of the Set table.
* @param[in] _count Number of basic element (pre-allocated) in the table. * @param[in] _count Number of basic element (pre-allocated) in the table.
*/ */
Set(int32_t _count = 0) : Set(int32_t _count = 0) :
m_data(), m_data(),
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) { m_comparator(nullptr) {
m_data.reserve(_count); m_data.reserve(_count);
// nothing to do // nothing to do
} }
@ -255,7 +265,7 @@ namespace etk {
template<typename... ETK_SET_TYPE_2> template<typename... ETK_SET_TYPE_2>
Set(const ETK_SET_TYPE_2& ... _args): Set(const ETK_SET_TYPE_2& ... _args):
m_data(), m_data(),
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) { m_comparator(nullptr) {
add(_args...); add(_args...);
} }
@ -337,6 +347,17 @@ namespace etk {
return; 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)); 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" ); //TK_CRITICAL("Vector : Error in data allocation request allocation:" << requestSize << "*" << (int32_t)(sizeof(ETK_VECTOR_TYPE)) << "bytes" );
return; return;
} }
ETK_MEM_FLIP_ID(dataTmp, m_data);
#ifdef DEBUG #ifdef DEBUG
// we place bad data to permit to detect stipid thing that is done in C++ code when developement is in progress. // 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 // 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[]) { int main(int argc, const char *argv[]) {
// init test engine: // init test engine:
etest::init(argc, argv); etest::init(argc, argv);
TEST_INFO("TEST ETK");
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }