[DEV] use a local placement new to allocate element in Vector only when needed and not for each element allocated and not used
This commit is contained in:
parent
ba6aeee852
commit
577d22a5f6
@ -246,9 +246,10 @@ namespace etk {
|
||||
* @param[in] _count Number of basic element in the table.
|
||||
* @param[in] _ordered select an ordered map or an onordered map.
|
||||
*/
|
||||
Map(int32_t _count = 0, bool _ordered=true) :
|
||||
m_data(_count),
|
||||
Map(size_t _count = 0, bool _ordered=true) :
|
||||
m_data(),
|
||||
m_ordered(_ordered) {
|
||||
m_data.reserve(_count);
|
||||
// nothing to do
|
||||
}
|
||||
/**
|
||||
@ -256,7 +257,7 @@ namespace etk {
|
||||
* @param[in] _obj Other Map to move
|
||||
*/
|
||||
Map(Map&& _obj):
|
||||
m_data(0),
|
||||
m_data(),
|
||||
m_ordered(true) {
|
||||
_obj.swap(*this);
|
||||
}
|
||||
|
@ -242,8 +242,9 @@ namespace etk {
|
||||
* @param[in] _count Number of basic element (pre-allocated) in the table.
|
||||
*/
|
||||
Set(int32_t _count = 0) :
|
||||
m_data(_count),
|
||||
m_data(),
|
||||
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) {
|
||||
m_data.reserve(_count);
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@ -253,7 +254,7 @@ namespace etk {
|
||||
*/
|
||||
template<typename... ETK_SET_TYPE_2>
|
||||
Set(const ETK_SET_TYPE_2& ... _args):
|
||||
m_data(0),
|
||||
m_data(),
|
||||
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) {
|
||||
add(_args...);
|
||||
}
|
||||
|
557
etk/Vector.hpp
557
etk/Vector.hpp
@ -8,6 +8,23 @@
|
||||
#include <etk/types.hpp>
|
||||
//#include <etk/debug.hpp>
|
||||
#include <etk/Stream.hpp>
|
||||
// better mode of vector ==> increate the code complexity
|
||||
#define ETK_ENABLE_PLACEMENT_NEW 1
|
||||
|
||||
//#define ETK_VECTOR_DEBUG(...) printf(__VA_ARGS__)
|
||||
#define ETK_VECTOR_DEBUG(...) do {} while (false)
|
||||
|
||||
// it is define bu generic "include <new>" ==> no double define of placement new
|
||||
#ifndef _NEW
|
||||
// Default placement versions of operator new.
|
||||
inline void* operator new(size_t, char* _p) throw() {
|
||||
ETK_VECTOR_DEBUG("plop\n");
|
||||
return _p;
|
||||
}
|
||||
inline void operator delete (void*, char*) throw() {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace etk {
|
||||
class Stream;
|
||||
@ -216,17 +233,32 @@ namespace etk {
|
||||
size_t m_size; //!< Number of element in the buffer
|
||||
size_t m_allocated; //!< Current allocated size
|
||||
public:
|
||||
/**
|
||||
* @brief Create an empty vector
|
||||
*/
|
||||
Vector():
|
||||
m_data(nullptr),
|
||||
m_size(0),
|
||||
m_allocated(0) {
|
||||
|
||||
}
|
||||
#if 0
|
||||
/**
|
||||
* @brief Create an empty vector
|
||||
* @param[in] _count Minimum request size of the Buffer
|
||||
*/
|
||||
Vector(int32_t _count = 0):
|
||||
Vector(size_t _count):
|
||||
m_data(nullptr),
|
||||
m_size(0),
|
||||
m_allocated(0) {
|
||||
changeAllocation(_count);
|
||||
// instanciate all objects
|
||||
for (size_t iii=0; iii<_count; ++iii) {
|
||||
new ((char*)&m_data[iii]) ETK_VECTOR_TYPE();
|
||||
}
|
||||
m_size = _count;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @brief List initializer (ex: etk::Vector<etk::String> plop = {"hello", world"}
|
||||
* @param[in] _element element to add in the vector
|
||||
@ -243,21 +275,42 @@ namespace etk {
|
||||
* @brief Re-copy constructor (copy all needed data)
|
||||
* @param[in] _obj Vector that might be copy
|
||||
*/
|
||||
Vector(const etk::Vector<ETK_VECTOR_TYPE>& _obj):
|
||||
m_data(nullptr),
|
||||
m_size(_obj.m_size),
|
||||
m_allocated(_obj.m_allocated) {
|
||||
// allocate all same data
|
||||
m_data = new ETK_VECTOR_TYPE[m_allocated];
|
||||
if (m_data == nullptr) {
|
||||
return;
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
Vector(const etk::Vector<ETK_VECTOR_TYPE>& _obj):
|
||||
m_data(nullptr),
|
||||
m_size(_obj.m_size),
|
||||
m_allocated(_obj.m_allocated) {
|
||||
// allocate all same data
|
||||
m_data = new ETK_VECTOR_TYPE[m_allocated];
|
||||
if (m_data == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Copy all data ...
|
||||
for(size_t iii=0; iii<m_allocated; iii++) {
|
||||
// copy operator ...
|
||||
m_data[iii] = _obj.m_data[iii];
|
||||
}
|
||||
}
|
||||
// Copy all data ...
|
||||
for(size_t iii=0; iii<m_allocated; iii++) {
|
||||
// copy operator ...
|
||||
m_data[iii] = _obj.m_data[iii];
|
||||
#else
|
||||
Vector(const etk::Vector<ETK_VECTOR_TYPE>& _obj):
|
||||
m_data(nullptr),
|
||||
m_size(0),
|
||||
m_allocated(0) {
|
||||
reserve(_obj.m_size);
|
||||
for(size_t iii=0; iii<_obj.m_size; iii++) {
|
||||
#if 0
|
||||
pushBack(_obj.m_data[iii]);
|
||||
#else
|
||||
new ((char*)&m_data[iii]) ETK_VECTOR_TYPE(etk::move(_obj.m_data[iii]));
|
||||
#endif
|
||||
}
|
||||
m_size = _obj.m_size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @brief Move operator of elements
|
||||
* @param[in] _obj Object to move
|
||||
*/
|
||||
Vector(etk::Vector<ETK_VECTOR_TYPE>&& _obj):
|
||||
m_data(_obj.m_data),
|
||||
m_size(_obj.m_size),
|
||||
@ -267,11 +320,25 @@ namespace etk {
|
||||
_obj.m_allocated = 0;
|
||||
}
|
||||
/**
|
||||
* @brief Destructor of the current Class
|
||||
* @brief Destructor of the current class
|
||||
*/
|
||||
~Vector() {
|
||||
if (m_data != nullptr) {
|
||||
delete[] m_data;
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
delete[] m_data;
|
||||
#else
|
||||
for(size_t iii=0; iii<m_size; iii++) {
|
||||
m_data[iii].~ETK_VECTOR_TYPE();
|
||||
#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
|
||||
for (size_t kkk=iii*sizeof(ETK_VECTOR_TYPE); kkk<sizeof(ETK_VECTOR_TYPE)*(iii+1); ++kkk) {
|
||||
((char*)m_data)[kkk] = 0xA5;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
delete[] (char*)m_data;
|
||||
#endif
|
||||
m_data = nullptr;
|
||||
}
|
||||
m_allocated = 0;
|
||||
@ -290,49 +357,91 @@ namespace etk {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Re-copy operator
|
||||
* @brief Move operator
|
||||
* @param[in] _obj Vector that might be copy
|
||||
* @return reference on the current re-copy vector
|
||||
*/
|
||||
Vector& operator=(const etk::Vector<ETK_VECTOR_TYPE> & _obj) {
|
||||
if (this != &_obj) {
|
||||
if (m_data != nullptr) {
|
||||
delete[] m_data;
|
||||
m_data = nullptr;
|
||||
}
|
||||
// Set the new value
|
||||
m_allocated = _obj.m_allocated;
|
||||
m_size = _obj.m_size;
|
||||
// allocate all same data
|
||||
m_data = new ETK_VECTOR_TYPE[m_allocated];
|
||||
if (m_data == nullptr) {
|
||||
return *this;
|
||||
}
|
||||
for(size_t iii=0; iii<m_allocated; iii++) {
|
||||
// copy operator ...
|
||||
m_data[iii] = _obj.m_data[iii];
|
||||
}
|
||||
Vector& operator=(etk::Vector<ETK_VECTOR_TYPE>&& _obj) {
|
||||
if(this != &_obj) {
|
||||
etk::swap(m_data, _obj.m_data);
|
||||
etk::swap(m_allocated, _obj.m_allocated);
|
||||
etk::swap(m_size, _obj.m_size);
|
||||
}
|
||||
// Return the current pointer
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @brief Re-copy operator
|
||||
* @param[in] _obj Vector that might be copy
|
||||
* @return reference on the current re-copy vector
|
||||
*/
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
Vector& operator=(const etk::Vector<ETK_VECTOR_TYPE>& _obj) {
|
||||
if (this != &_obj) {
|
||||
if (m_data != nullptr) {
|
||||
delete[] m_data;
|
||||
m_data = nullptr;
|
||||
}
|
||||
// Set the new value
|
||||
m_allocated = _obj.m_allocated;
|
||||
m_size = _obj.m_size;
|
||||
// allocate all same data
|
||||
m_data = new ETK_VECTOR_TYPE[m_allocated];
|
||||
if (m_data == nullptr) {
|
||||
return *this;
|
||||
}
|
||||
for(size_t iii=0; iii<m_allocated; iii++) {
|
||||
// copy operator ...
|
||||
m_data[iii] = _obj.m_data[iii];
|
||||
}
|
||||
}
|
||||
// Return the current pointer
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
Vector& operator=(const etk::Vector<ETK_VECTOR_TYPE>& _obj) {
|
||||
// remove all previous elements
|
||||
clear();
|
||||
// Force a specicfic size
|
||||
reserve(_obj.m_size);
|
||||
for(size_t iii=0; iii<_obj.m_size; iii++) {
|
||||
#if 0
|
||||
pushBack(_obj.m_data[iii]);
|
||||
#else
|
||||
new ((char*)&m_data[iii]) ETK_VECTOR_TYPE(etk::move(_obj.m_data[iii]));
|
||||
#endif
|
||||
}
|
||||
m_size = _obj.m_size;
|
||||
// Return the current pointer
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Add at the Last position of the Vector
|
||||
* @param[in] _obj Element to add at the end of vector
|
||||
*/
|
||||
Vector& operator+= (const etk::Vector<ETK_VECTOR_TYPE>& _obj) {
|
||||
size_t numberElement = _obj.size();
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+numberElement);
|
||||
if (m_size<=idElement) {
|
||||
//TK_CRITICAL("allocation error");
|
||||
return *this;
|
||||
}
|
||||
for(size_t iii=0; iii<numberElement; iii++) {
|
||||
// copy operator ...
|
||||
m_data[idElement+iii] = etk::move(_obj.m_data[iii]);
|
||||
}
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
size_t numberElement = _obj.size();
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+numberElement);
|
||||
if (m_size <= idElement) {
|
||||
//TK_CRITICAL("allocation error");
|
||||
return *this;
|
||||
}
|
||||
for(size_t iii=0; iii<numberElement; iii++) {
|
||||
// copy operator ...
|
||||
m_data[idElement+iii] = etk::move(_obj.m_data[iii]);
|
||||
}
|
||||
#else
|
||||
reserve(m_size + _obj.size());
|
||||
for(size_t iii=0; iii<_obj.size(); iii++) {
|
||||
// copy operator ...
|
||||
new ((char*)&m_data[m_size+iii]) ETK_VECTOR_TYPE(etk::move(_obj.m_data[iii]));
|
||||
}
|
||||
m_size += _obj.size();
|
||||
#endif
|
||||
// Return the current pointer
|
||||
return *this;
|
||||
}
|
||||
@ -351,24 +460,6 @@ namespace etk {
|
||||
bool empty() const {
|
||||
return m_size == 0;
|
||||
}
|
||||
/**
|
||||
* @brief Resize the vector with a basic element
|
||||
* @param[in] _newSize New size of the vector
|
||||
*/
|
||||
void resize(size_t _newSize, const ETK_VECTOR_TYPE& _basicElement) {
|
||||
size_t idElement = m_size;
|
||||
resize(_newSize);
|
||||
if (m_size != _newSize) {
|
||||
//TK_CRITICAL("error to resize vector");
|
||||
return;
|
||||
}
|
||||
if (_newSize > idElement) {
|
||||
// initialize data ...
|
||||
for(size_t iii=idElement; iii<_newSize; iii++) {
|
||||
m_data[iii] = _basicElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Get the Allocated size in the vector
|
||||
* @return The size of allocation
|
||||
@ -440,26 +531,38 @@ namespace etk {
|
||||
* @param[in] _item Element to add at the end of vector
|
||||
*/
|
||||
void pushBack(ETK_VECTOR_TYPE&& _item) {
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+1);
|
||||
if (idElement < m_size) {
|
||||
m_data[idElement] = etk::move(_item);
|
||||
} else {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
}
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+1);
|
||||
if (idElement < m_size) {
|
||||
m_data[idElement] = etk::move(_item);
|
||||
} else {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
}
|
||||
#else
|
||||
reserve(m_size+1);
|
||||
new ((char*)&m_data[m_size]) ETK_VECTOR_TYPE(etk::move(_item));
|
||||
m_size += 1;
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief Add at the Last position of the Vector
|
||||
* @param[in] _item Element to add at the end of vector
|
||||
*/
|
||||
void pushBack(const ETK_VECTOR_TYPE& _item) {
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+1);
|
||||
if (idElement < m_size) {
|
||||
m_data[idElement] = etk::move(_item);
|
||||
} else {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
}
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+1);
|
||||
if (idElement < m_size) {
|
||||
m_data[idElement] = etk::move(_item);
|
||||
} else {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
}
|
||||
#else
|
||||
reserve(m_size+1);
|
||||
new ((char*)&m_data[m_size]) ETK_VECTOR_TYPE(etk::move(_item));
|
||||
m_size += 1;
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief Add at the Last position of the Vector
|
||||
@ -470,15 +573,27 @@ namespace etk {
|
||||
if (_item == nullptr) {
|
||||
return;
|
||||
}
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+_nbElement);
|
||||
if (idElement > m_size) {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<_nbElement; iii++) {
|
||||
m_data[idElement+iii] = _item[iii];
|
||||
}
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
size_t idElement = m_size;
|
||||
resize(m_size+_nbElement);
|
||||
if (idElement > m_size) {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<_nbElement; iii++) {
|
||||
m_data[idElement+iii] = _item[iii];
|
||||
}
|
||||
#else
|
||||
reserve(m_size+_nbElement);
|
||||
if (m_size > m_allocated) {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
return;
|
||||
}
|
||||
for (size_t iii=0; iii<_nbElement; iii++) {
|
||||
new ((char*)&m_data[m_size+iii]) ETK_VECTOR_TYPE(_item[iii]);
|
||||
m_size += 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
void pushBackN(const ETK_VECTOR_TYPE& _value) {
|
||||
@ -503,7 +618,7 @@ namespace etk {
|
||||
*/
|
||||
void popBack() {
|
||||
if(m_size>0) {
|
||||
resize(m_size-1);
|
||||
resizeDown(m_size-1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -511,7 +626,7 @@ namespace etk {
|
||||
*/
|
||||
void clear() {
|
||||
if(m_size>0) {
|
||||
resize(0);
|
||||
resizeDown(0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -526,25 +641,57 @@ namespace etk {
|
||||
pushBack(_item, _nbElement);
|
||||
return;
|
||||
}
|
||||
size_t idElement = m_size;
|
||||
// Request resize of the current buffer
|
||||
resize(m_size+_nbElement);
|
||||
if (idElement >= m_size) {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
return;
|
||||
}
|
||||
// move current data (after the position)
|
||||
size_t sizeToMove = (idElement - _pos);
|
||||
if (sizeToMove > 0) {
|
||||
for (size_t iii=1; iii<=sizeToMove; iii++) {
|
||||
// tODO: better explicite the swap...
|
||||
m_data[m_size-iii] = etk::move(m_data[idElement-iii]);
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
size_t idElement = m_size;
|
||||
// Request resize of the current buffer
|
||||
resize(m_size+_nbElement);
|
||||
if (idElement >= m_size) {
|
||||
//TK_ERROR("Resize does not work correctly ... not added item");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// affectation of all input element
|
||||
for (size_t iii=0; iii<_nbElement; iii++) {
|
||||
m_data[_pos+iii] = etk::move(_item[iii]);
|
||||
}
|
||||
// move current data (after the position)
|
||||
size_t sizeToMove = (idElement - _pos);
|
||||
if (sizeToMove > 0) {
|
||||
for (size_t iii=1; iii<=sizeToMove; iii++) {
|
||||
// tODO: better explicite the swap...
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
m_data[m_size-iii] = etk::move(m_data[idElement-iii]);
|
||||
#else
|
||||
etk::swap(m_data[m_size-iii], m_data[idElement-iii]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// affectation of all input element
|
||||
for (size_t iii=0; iii<_nbElement; iii++) {
|
||||
m_data[_pos+iii] = etk::move(_item[iii]);
|
||||
}
|
||||
#else
|
||||
// move current data (after the position)
|
||||
size_t sizeToMove = (m_size - _pos);
|
||||
// Request resize of the current buffer
|
||||
reserve(m_size+_nbElement);
|
||||
if (sizeToMove > 0) {
|
||||
for (size_t iii=1; iii<=sizeToMove; iii++) {
|
||||
// placement allocate of the element
|
||||
new ((char*)&m_data[m_size+_nbElement-iii]) ETK_VECTOR_TYPE(etk::move(m_data[m_size-iii]));
|
||||
// Remove previous element ==> simplify code.
|
||||
m_data[m_size-iii].~ETK_VECTOR_TYPE();
|
||||
#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
|
||||
for (size_t kkk=(m_size-iii)*sizeof(ETK_VECTOR_TYPE); kkk<sizeof(ETK_VECTOR_TYPE)*((m_size-iii)+1); ++kkk) {
|
||||
((char*)m_data)[kkk] = 0xA5;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
// affectation of all input element
|
||||
for (size_t iii=0; iii<_nbElement; iii++) {
|
||||
new ((char*)&m_data[_pos-iii]) ETK_VECTOR_TYPE(etk::move(_item[iii]));
|
||||
}
|
||||
m_size += _nbElement;
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief Insert one element in the Vector at a specific position
|
||||
@ -568,23 +715,29 @@ namespace etk {
|
||||
* @param[in] _nbElement number of element to remove
|
||||
*/
|
||||
void eraseLen(size_t _pos, size_t _nbElement) {
|
||||
if (_pos>m_size) {
|
||||
ETK_VECTOR_DEBUG("Erase len %zu %zu\n", _pos, _nbElement);
|
||||
if (_pos > m_size) {
|
||||
//TK_ERROR(" can not Erase Len Element at this position : " << _pos << " > " << m_size);
|
||||
return;
|
||||
}
|
||||
if (_pos+_nbElement>m_size) {
|
||||
if (_pos + _nbElement > m_size) {
|
||||
_nbElement = m_size - _pos;
|
||||
}
|
||||
ETK_VECTOR_DEBUG("Erase len %zu %zu\n", _pos, _nbElement);
|
||||
size_t idElement = m_size;
|
||||
// move current data
|
||||
size_t sizeToMove = (idElement - (_pos+_nbElement));
|
||||
if ( 0 < sizeToMove) {
|
||||
for (size_t iii=0; iii<sizeToMove; iii++) {
|
||||
m_data[_pos+iii] = etk::move(m_data[_pos+_nbElement+iii]);
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
m_data[_pos+iii] = etk::move(m_data[_pos+_nbElement+iii]);
|
||||
#else
|
||||
etk::swap(m_data[_pos+iii], m_data[_pos+_nbElement+iii]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Request resize of the current buffer
|
||||
resize(m_size-_nbElement);
|
||||
resizeDown(m_size-_nbElement);
|
||||
}
|
||||
/**
|
||||
* @brief Remove one element
|
||||
@ -599,6 +752,7 @@ namespace etk {
|
||||
* @return An iterator on the new element at this position.
|
||||
*/
|
||||
Iterator erase(const Iterator& _it) {
|
||||
ETK_VECTOR_DEBUG("Erase IT \n");
|
||||
eraseLen(_it.getCurrent(), 1);
|
||||
return position(_it.getCurrent());
|
||||
}
|
||||
@ -615,24 +769,28 @@ namespace etk {
|
||||
* @param[in] _posEnd Last position number
|
||||
*/
|
||||
void erase(size_t _pos, size_t _posEnd) {
|
||||
if (_pos>m_size) {
|
||||
if (_pos > m_size) {
|
||||
//TK_ERROR(" can not Erase Element at this position : " << _pos << " > " << m_size);
|
||||
return;
|
||||
}
|
||||
if (_posEnd>m_size) {
|
||||
if (_posEnd > m_size) {
|
||||
_posEnd = m_size;
|
||||
}
|
||||
size_t nbElement = m_size - _pos;
|
||||
size_t tmpSize = m_size;
|
||||
// move current data
|
||||
// move current data (to the end) ==> auto removed by the resize()
|
||||
size_t sizeToMove = (tmpSize - (_pos+nbElement));
|
||||
if ( 0 < sizeToMove) {
|
||||
for (size_t iii=0; iii<sizeToMove; iii++) {
|
||||
m_data[_pos+iii] = etk::move(m_data[_pos+nbElement+iii]);
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
m_data[_pos+iii] = etk::move(m_data[_pos+nbElement+iii]);
|
||||
#else
|
||||
etk::swap(m_data[_pos+iii], m_data[_pos+nbElement+iii]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Request resize of the current buffer
|
||||
resize(m_size-nbElement);
|
||||
resizeDown(m_size-nbElement);
|
||||
}
|
||||
void erase(const Iterator& _pos, const Iterator& _posEnd) {
|
||||
erase(_pos.getCurrent(), _posEnd.getCurrent());
|
||||
@ -693,17 +851,118 @@ namespace etk {
|
||||
return position(size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resize the vector with a basic element
|
||||
* @param[in] _newSize New size of the vector
|
||||
*/
|
||||
void resize(size_t _newSize, const ETK_VECTOR_TYPE& _basicElement) {
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
size_t idElement = m_size;
|
||||
resize(_newSize);
|
||||
if (m_size != _newSize) {
|
||||
//TK_CRITICAL("error to resize vector");
|
||||
return;
|
||||
}
|
||||
if (_newSize > idElement) {
|
||||
// initialize data ...
|
||||
for(size_t iii=idElement; iii<_newSize; iii++) {
|
||||
m_data[iii] = _basicElement;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Reallocate memory
|
||||
if (_newSize > m_size) {
|
||||
if (_newSize > m_allocated) {
|
||||
changeAllocation(_newSize);
|
||||
}
|
||||
for (size_t iii=m_size; iii<_newSize; ++iii) {
|
||||
new ((char*)&m_data[iii]) ETK_VECTOR_TYPE(_basicElement);
|
||||
}
|
||||
m_size = _newSize;
|
||||
return;
|
||||
} else if (_newSize == m_size) {
|
||||
return;
|
||||
}
|
||||
for (size_t iii=m_size; iii<_newSize; ++iii) {
|
||||
m_data[iii].~ETK_VECTOR_TYPE();
|
||||
#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
|
||||
for (size_t kkk=iii*sizeof(ETK_VECTOR_TYPE); kkk<sizeof(ETK_VECTOR_TYPE)*(iii+1); ++kkk) {
|
||||
((char*)m_data)[kkk] = 0xA5;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_size = _newSize;
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief Change the current size of the vector
|
||||
* @param[in] _newSize New requested size of element in the vector
|
||||
*/
|
||||
void resize(size_t _newSize) {
|
||||
ETK_VECTOR_DEBUG("Resize %zu => %zu\n", m_size, _newSize);
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
// Reallocate memory
|
||||
if (_newSize > m_allocated) {
|
||||
changeAllocation(_newSize);
|
||||
} else if (_newSize == m_allocated) {
|
||||
return;
|
||||
}
|
||||
for
|
||||
m_size = _newSize;
|
||||
#else
|
||||
// Reallocate memory
|
||||
if (_newSize > m_size) {
|
||||
if (_newSize > m_allocated) {
|
||||
changeAllocation(_newSize);
|
||||
}
|
||||
for (size_t iii=m_size; iii<_newSize; ++iii) {
|
||||
new ((char*)&m_data[iii]) ETK_VECTOR_TYPE();
|
||||
}
|
||||
} else if (_newSize == m_size) {
|
||||
return;
|
||||
}
|
||||
ETK_VECTOR_DEBUG("Reduce %zu => %zu\n", m_size, _newSize);
|
||||
for (size_t iii=_newSize; iii<m_size; ++iii) {
|
||||
m_data[iii].~ETK_VECTOR_TYPE();
|
||||
#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
|
||||
for (size_t kkk=iii*sizeof(ETK_VECTOR_TYPE); kkk<sizeof(ETK_VECTOR_TYPE)*(iii+1); ++kkk) {
|
||||
((char*)m_data)[kkk] = 0xA5;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_size = _newSize;
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
#ifdef ETK_ENABLE_PLACEMENT_NEW
|
||||
void resizeDown(size_t _newSize) {
|
||||
ETK_VECTOR_DEBUG("Resize %zu => %zu\n", m_size, _newSize);
|
||||
// Reallocate memory
|
||||
if (_newSize > m_allocated) {
|
||||
changeAllocation(_newSize);
|
||||
ETK_VECTOR_DEBUG("Resize Down %zu => %zu\n", m_size, _newSize);
|
||||
return;
|
||||
} else if (_newSize == m_allocated) {
|
||||
return;
|
||||
}
|
||||
ETK_VECTOR_DEBUG("Reduce %zu => %zu\n", m_size, _newSize);
|
||||
for (size_t iii=_newSize; iii<m_size; ++iii) {
|
||||
m_data[iii].~ETK_VECTOR_TYPE();
|
||||
#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
|
||||
for (size_t kkk=iii*sizeof(ETK_VECTOR_TYPE); kkk<sizeof(ETK_VECTOR_TYPE)*(iii+1); ++kkk) {
|
||||
((char*)m_data)[kkk] = 0xA5;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_size = _newSize;
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
/**
|
||||
* @brief Force the container to have a minimum size in memory allocation
|
||||
* @param[in] _size Size in byte that is requested.
|
||||
@ -721,7 +980,7 @@ namespace etk {
|
||||
*/
|
||||
void changeAllocation(size_t _newSize) {
|
||||
size_t requestSize = m_allocated;
|
||||
// set the size with the correct chose type :
|
||||
// set the size with the correct chose type:
|
||||
if (_newSize == requestSize) {
|
||||
return;
|
||||
} else if (_newSize < requestSize) {
|
||||
@ -743,31 +1002,73 @@ namespace etk {
|
||||
// check if something is allocated :
|
||||
if (m_data == nullptr) {
|
||||
// no data allocated ==> request an allocation (might be the first)
|
||||
m_data = new ETK_VECTOR_TYPE[requestSize];
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
m_data = new ETK_VECTOR_TYPE[requestSize];
|
||||
#else
|
||||
m_data = (ETK_VECTOR_TYPE*)(new char[sizeof(ETK_VECTOR_TYPE)*requestSize]);
|
||||
#endif
|
||||
if (m_data == nullptr) {
|
||||
//TK_CRITICAL("Vector : Error in data allocation request allocation:" << requestSize << "*" << (int32_t)(sizeof(ETK_VECTOR_TYPE)) << "bytes" );
|
||||
m_allocated = 0;
|
||||
return;
|
||||
}
|
||||
#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
|
||||
for (size_t kkk=0; kkk<sizeof(ETK_VECTOR_TYPE)*requestSize; ++kkk) {
|
||||
((char*)m_data)[kkk] = 0x5A;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// allocate a new pool of data:
|
||||
ETK_VECTOR_TYPE* m_dataTmp = new ETK_VECTOR_TYPE[requestSize];
|
||||
if (m_dataTmp == nullptr) {
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
ETK_VECTOR_TYPE* dataTmp = new ETK_VECTOR_TYPE[requestSize];
|
||||
#else
|
||||
ETK_VECTOR_TYPE* dataTmp = (ETK_VECTOR_TYPE*)(new char[sizeof(ETK_VECTOR_TYPE)*requestSize]);
|
||||
#endif
|
||||
if (dataTmp == nullptr) {
|
||||
//TK_CRITICAL("Vector : Error in data allocation request allocation:" << requestSize << "*" << (int32_t)(sizeof(ETK_VECTOR_TYPE)) << "bytes" );
|
||||
m_allocated = 0;
|
||||
#if 0
|
||||
m_allocated = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#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
|
||||
for (size_t kkk=0; kkk<sizeof(ETK_VECTOR_TYPE)*requestSize; ++kkk) {
|
||||
((char*)dataTmp)[kkk] = 0x5A;
|
||||
}
|
||||
#endif
|
||||
// copy data in the new pool
|
||||
size_t nbElements = etk::min(requestSize, m_allocated);
|
||||
for(size_t iii=0; iii<nbElements; iii++) {
|
||||
m_dataTmp[iii] = etk::move(m_data[iii]);
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
dataTmp[iii] = etk::move(m_data[iii]);
|
||||
#else
|
||||
// Move in the new element
|
||||
new ((char*)&dataTmp[iii]) ETK_VECTOR_TYPE(etk::move(m_data[iii]));
|
||||
// Remove the old one.
|
||||
m_data[iii].~ETK_VECTOR_TYPE();
|
||||
#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
|
||||
for (size_t kkk=iii*sizeof(ETK_VECTOR_TYPE); kkk<sizeof(ETK_VECTOR_TYPE)*(iii+1); ++kkk) {
|
||||
((char*)m_data)[kkk] = 0xA5;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
// switch pointer:
|
||||
ETK_VECTOR_TYPE* m_dataTmp2 = m_data;
|
||||
m_data = m_dataTmp;
|
||||
ETK_VECTOR_TYPE* dataTmp2 = m_data;
|
||||
m_data = dataTmp;
|
||||
// remove old pool
|
||||
if (m_dataTmp2 != nullptr) {
|
||||
delete[] m_dataTmp2;
|
||||
if (dataTmp2 != nullptr) {
|
||||
#ifndef ETK_ENABLE_PLACEMENT_NEW
|
||||
delete[] dataTmp2;
|
||||
#else
|
||||
delete[] (char*)dataTmp2;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// set the new allocation size
|
||||
@ -806,7 +1107,7 @@ namespace etk {
|
||||
return false;
|
||||
}
|
||||
// first step : check the size ...
|
||||
if (m_size!=_obj.m_size) {
|
||||
if (m_size != _obj.m_size) {
|
||||
return true;
|
||||
}
|
||||
if( m_data == nullptr
|
||||
|
@ -13,40 +13,40 @@
|
||||
TEST(TestString, constructor) {
|
||||
// Test contructor value
|
||||
etk::String test0;
|
||||
EXPECT_FLOAT_EQ(test0.size(), 0);
|
||||
EXPECT_FLOAT_EQ(test0.c_str()[0], '\0');
|
||||
EXPECT_EQ(test0.size(), 0);
|
||||
EXPECT_EQ(test0.c_str()[0], '\0');
|
||||
|
||||
etk::String test1("hello");
|
||||
EXPECT_FLOAT_EQ(test1.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'e');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'l');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'l');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 'o');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], '\0');
|
||||
EXPECT_EQ(test1.size(), 5);
|
||||
EXPECT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_EQ(test1.c_str()[1], 'e');
|
||||
EXPECT_EQ(test1.c_str()[2], 'l');
|
||||
EXPECT_EQ(test1.c_str()[3], 'l');
|
||||
EXPECT_EQ(test1.c_str()[4], 'o');
|
||||
EXPECT_EQ(test1.c_str()[5], '\0');
|
||||
|
||||
etk::String test2(test1);
|
||||
EXPECT_FLOAT_EQ(test2.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[1], 'e');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[2], 'l');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[3], 'l');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[4], 'o');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[5], '\0');
|
||||
EXPECT_EQ(test2.size(), 5);
|
||||
EXPECT_EQ(test2.c_str()[0], 'h');
|
||||
EXPECT_EQ(test2.c_str()[1], 'e');
|
||||
EXPECT_EQ(test2.c_str()[2], 'l');
|
||||
EXPECT_EQ(test2.c_str()[3], 'l');
|
||||
EXPECT_EQ(test2.c_str()[4], 'o');
|
||||
EXPECT_EQ(test2.c_str()[5], '\0');
|
||||
|
||||
etk::String test3(test1, 2);
|
||||
EXPECT_FLOAT_EQ(test3.size(), 3);
|
||||
EXPECT_FLOAT_EQ(test3.c_str()[0], 'l');
|
||||
EXPECT_FLOAT_EQ(test3.c_str()[1], 'l');
|
||||
EXPECT_FLOAT_EQ(test3.c_str()[2], 'o');
|
||||
EXPECT_FLOAT_EQ(test3.c_str()[3], '\0');
|
||||
EXPECT_EQ(test3.size(), 3);
|
||||
EXPECT_EQ(test3.c_str()[0], 'l');
|
||||
EXPECT_EQ(test3.c_str()[1], 'l');
|
||||
EXPECT_EQ(test3.c_str()[2], 'o');
|
||||
EXPECT_EQ(test3.c_str()[3], '\0');
|
||||
|
||||
etk::String test4(test1, 1, 3);
|
||||
EXPECT_FLOAT_EQ(test4.size(), 3);
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[0], 'e');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[1], 'l');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[2], 'l');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[3], '\0');
|
||||
EXPECT_EQ(test4.size(), 3);
|
||||
EXPECT_EQ(test4.c_str()[0], 'e');
|
||||
EXPECT_EQ(test4.c_str()[1], 'l');
|
||||
EXPECT_EQ(test4.c_str()[2], 'l');
|
||||
EXPECT_EQ(test4.c_str()[3], '\0');
|
||||
|
||||
}
|
||||
|
||||
@ -55,173 +55,173 @@ TEST(TestString, equality) {
|
||||
etk::String test4("maeau");
|
||||
|
||||
test4 = 'c';
|
||||
EXPECT_FLOAT_EQ(test4.size(), 1);
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[0], 'c');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[1], '\0');
|
||||
EXPECT_EQ(test4.size(), 1);
|
||||
EXPECT_EQ(test4.c_str()[0], 'c');
|
||||
EXPECT_EQ(test4.c_str()[1], '\0');
|
||||
|
||||
test4 = "prout";
|
||||
EXPECT_FLOAT_EQ(test4.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[0], 'p');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[1], 'r');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[2], 'o');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[3], 'u');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[4], 't');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[5], '\0');
|
||||
EXPECT_EQ(test4.size(), 5);
|
||||
EXPECT_EQ(test4.c_str()[0], 'p');
|
||||
EXPECT_EQ(test4.c_str()[1], 'r');
|
||||
EXPECT_EQ(test4.c_str()[2], 'o');
|
||||
EXPECT_EQ(test4.c_str()[3], 'u');
|
||||
EXPECT_EQ(test4.c_str()[4], 't');
|
||||
EXPECT_EQ(test4.c_str()[5], '\0');
|
||||
|
||||
test4 = test2;
|
||||
EXPECT_FLOAT_EQ(test4.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[1], 'e');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[2], 'l');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[3], 'l');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[4], 'o');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[5], '\0');
|
||||
EXPECT_EQ(test4.size(), 5);
|
||||
EXPECT_EQ(test4.c_str()[0], 'h');
|
||||
EXPECT_EQ(test4.c_str()[1], 'e');
|
||||
EXPECT_EQ(test4.c_str()[2], 'l');
|
||||
EXPECT_EQ(test4.c_str()[3], 'l');
|
||||
EXPECT_EQ(test4.c_str()[4], 'o');
|
||||
EXPECT_EQ(test4.c_str()[5], '\0');
|
||||
}
|
||||
|
||||
TEST(TestString, swap) {
|
||||
etk::String test2("hello");
|
||||
etk::String test4 = "plo";
|
||||
test4.swap(test2);
|
||||
EXPECT_FLOAT_EQ(test4.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[1], 'e');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[2], 'l');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[3], 'l');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[4], 'o');
|
||||
EXPECT_FLOAT_EQ(test4.c_str()[5], '\0');
|
||||
EXPECT_FLOAT_EQ(test2.size(), 3);
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[0], 'p');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[1], 'l');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[2], 'o');
|
||||
EXPECT_FLOAT_EQ(test2.c_str()[3], '\0');
|
||||
EXPECT_EQ(test4.size(), 5);
|
||||
EXPECT_EQ(test4.c_str()[0], 'h');
|
||||
EXPECT_EQ(test4.c_str()[1], 'e');
|
||||
EXPECT_EQ(test4.c_str()[2], 'l');
|
||||
EXPECT_EQ(test4.c_str()[3], 'l');
|
||||
EXPECT_EQ(test4.c_str()[4], 'o');
|
||||
EXPECT_EQ(test4.c_str()[5], '\0');
|
||||
EXPECT_EQ(test2.size(), 3);
|
||||
EXPECT_EQ(test2.c_str()[0], 'p');
|
||||
EXPECT_EQ(test2.c_str()[1], 'l');
|
||||
EXPECT_EQ(test2.c_str()[2], 'o');
|
||||
EXPECT_EQ(test2.c_str()[3], '\0');
|
||||
|
||||
}
|
||||
|
||||
TEST(TestString, equalityComparison) {
|
||||
etk::String test1("hello");
|
||||
etk::String test2("hello2");
|
||||
EXPECT_FLOAT_EQ(test1 == test2, false);
|
||||
EXPECT_FLOAT_EQ(test1 != test2, true);
|
||||
EXPECT_EQ(test1 == test2, false);
|
||||
EXPECT_EQ(test1 != test2, true);
|
||||
|
||||
test1 = "hello2";
|
||||
EXPECT_FLOAT_EQ(test1 != test2, false);
|
||||
EXPECT_FLOAT_EQ(test1 == test2, true);
|
||||
EXPECT_EQ(test1 != test2, false);
|
||||
EXPECT_EQ(test1 == test2, true);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestString, resize) {
|
||||
etk::String test1("hello");
|
||||
test1.resize(0);
|
||||
EXPECT_FLOAT_EQ(test1.size(), 0);
|
||||
EXPECT_EQ(test1.size(), 0);
|
||||
test1.resize(3);
|
||||
EXPECT_FLOAT_EQ(test1.size(), 3);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], '\0');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], '\0');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], '\0');
|
||||
EXPECT_EQ(test1.size(), 3);
|
||||
EXPECT_EQ(test1.c_str()[0], '\0');
|
||||
EXPECT_EQ(test1.c_str()[1], '\0');
|
||||
EXPECT_EQ(test1.c_str()[2], '\0');
|
||||
EXPECT_EQ(test1.c_str()[3], '\0');
|
||||
test1.resize(2, 'g');
|
||||
EXPECT_FLOAT_EQ(test1.size(), 2);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], '\0');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
|
||||
EXPECT_EQ(test1.size(), 2);
|
||||
EXPECT_EQ(test1.c_str()[0], '\0');
|
||||
EXPECT_EQ(test1.c_str()[1], '\0');
|
||||
test1.resize(5, 'g');
|
||||
EXPECT_FLOAT_EQ(test1.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], '\0');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], '\0');
|
||||
EXPECT_EQ(test1.size(), 5);
|
||||
EXPECT_EQ(test1.c_str()[0], '\0');
|
||||
EXPECT_EQ(test1.c_str()[1], '\0');
|
||||
EXPECT_EQ(test1.c_str()[2], 'g');
|
||||
EXPECT_EQ(test1.c_str()[3], 'g');
|
||||
EXPECT_EQ(test1.c_str()[4], 'g');
|
||||
EXPECT_EQ(test1.c_str()[5], '\0');
|
||||
}
|
||||
|
||||
|
||||
TEST(TestString, add) {
|
||||
etk::String test1("h");
|
||||
test1 += 'r';
|
||||
EXPECT_FLOAT_EQ(test1.size(), 2);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'r');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], '\0');
|
||||
EXPECT_EQ(test1.size(), 2);
|
||||
EXPECT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_EQ(test1.c_str()[1], 'r');
|
||||
EXPECT_EQ(test1.c_str()[2], '\0');
|
||||
test1 += "kg";
|
||||
EXPECT_FLOAT_EQ(test1.size(), 4);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'r');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'k');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], '\0');
|
||||
EXPECT_EQ(test1.size(), 4);
|
||||
EXPECT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_EQ(test1.c_str()[1], 'r');
|
||||
EXPECT_EQ(test1.c_str()[2], 'k');
|
||||
EXPECT_EQ(test1.c_str()[3], 'g');
|
||||
EXPECT_EQ(test1.c_str()[4], '\0');
|
||||
test1 += etk::String("Ui");
|
||||
EXPECT_FLOAT_EQ(test1.size(), 6);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'r');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'k');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 'U');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], 'i');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[6], '\0');
|
||||
EXPECT_EQ(test1.size(), 6);
|
||||
EXPECT_EQ(test1.c_str()[0], 'h');
|
||||
EXPECT_EQ(test1.c_str()[1], 'r');
|
||||
EXPECT_EQ(test1.c_str()[2], 'k');
|
||||
EXPECT_EQ(test1.c_str()[3], 'g');
|
||||
EXPECT_EQ(test1.c_str()[4], 'U');
|
||||
EXPECT_EQ(test1.c_str()[5], 'i');
|
||||
EXPECT_EQ(test1.c_str()[6], '\0');
|
||||
}
|
||||
|
||||
TEST(TestString, insert) {
|
||||
etk::String test1("hrkgUi");
|
||||
test1.insert(0, 'F');
|
||||
EXPECT_FLOAT_EQ(test1.size(), 7);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'F');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'r');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'k');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], 'U');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[6], 'i');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[7], '\0');
|
||||
EXPECT_EQ(test1.size(), 7);
|
||||
EXPECT_EQ(test1.c_str()[0], 'F');
|
||||
EXPECT_EQ(test1.c_str()[1], 'h');
|
||||
EXPECT_EQ(test1.c_str()[2], 'r');
|
||||
EXPECT_EQ(test1.c_str()[3], 'k');
|
||||
EXPECT_EQ(test1.c_str()[4], 'g');
|
||||
EXPECT_EQ(test1.c_str()[5], 'U');
|
||||
EXPECT_EQ(test1.c_str()[6], 'i');
|
||||
EXPECT_EQ(test1.c_str()[7], '\0');
|
||||
test1.insert(7, 'Z');
|
||||
EXPECT_FLOAT_EQ(test1.size(), 8);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'F');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'r');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'k');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], 'U');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[6], 'i');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[7], 'Z');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[8], '\0');
|
||||
EXPECT_EQ(test1.size(), 8);
|
||||
EXPECT_EQ(test1.c_str()[0], 'F');
|
||||
EXPECT_EQ(test1.c_str()[1], 'h');
|
||||
EXPECT_EQ(test1.c_str()[2], 'r');
|
||||
EXPECT_EQ(test1.c_str()[3], 'k');
|
||||
EXPECT_EQ(test1.c_str()[4], 'g');
|
||||
EXPECT_EQ(test1.c_str()[5], 'U');
|
||||
EXPECT_EQ(test1.c_str()[6], 'i');
|
||||
EXPECT_EQ(test1.c_str()[7], 'Z');
|
||||
EXPECT_EQ(test1.c_str()[8], '\0');
|
||||
test1.insert(2, 'H');
|
||||
EXPECT_FLOAT_EQ(test1.size(), 9);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'F');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'H');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'r');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 'k');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[6], 'U');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[7], 'i');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[8], 'Z');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[9], '\0');
|
||||
EXPECT_EQ(test1.size(), 9);
|
||||
EXPECT_EQ(test1.c_str()[0], 'F');
|
||||
EXPECT_EQ(test1.c_str()[1], 'h');
|
||||
EXPECT_EQ(test1.c_str()[2], 'H');
|
||||
EXPECT_EQ(test1.c_str()[3], 'r');
|
||||
EXPECT_EQ(test1.c_str()[4], 'k');
|
||||
EXPECT_EQ(test1.c_str()[5], 'g');
|
||||
EXPECT_EQ(test1.c_str()[6], 'U');
|
||||
EXPECT_EQ(test1.c_str()[7], 'i');
|
||||
EXPECT_EQ(test1.c_str()[8], 'Z');
|
||||
EXPECT_EQ(test1.c_str()[9], '\0');
|
||||
}
|
||||
|
||||
TEST(TestString, eraseLen) {
|
||||
etk::String test1("hrkgUi");
|
||||
test1.erase(0, 3);
|
||||
EXPECT_FLOAT_EQ(test1.size(), 3);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'U');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'i');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], '\0');
|
||||
EXPECT_EQ(test1.size(), 3);
|
||||
EXPECT_EQ(test1.c_str()[0], 'g');
|
||||
EXPECT_EQ(test1.c_str()[1], 'U');
|
||||
EXPECT_EQ(test1.c_str()[2], 'i');
|
||||
EXPECT_EQ(test1.c_str()[3], '\0');
|
||||
test1.erase(1, 1);
|
||||
EXPECT_FLOAT_EQ(test1.size(), 2);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'i');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], '\0');
|
||||
EXPECT_EQ(test1.size(), 2);
|
||||
EXPECT_EQ(test1.c_str()[0], 'g');
|
||||
EXPECT_EQ(test1.c_str()[1], 'i');
|
||||
EXPECT_EQ(test1.c_str()[2], '\0');
|
||||
test1.erase(1, 100);
|
||||
EXPECT_FLOAT_EQ(test1.size(), 1);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'g');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
|
||||
EXPECT_EQ(test1.size(), 1);
|
||||
EXPECT_EQ(test1.c_str()[0], 'g');
|
||||
EXPECT_EQ(test1.c_str()[1], '\0');
|
||||
}
|
||||
|
||||
TEST(TestString, additionExtern) {
|
||||
etk::String test1 = "aa" + etk::String("he") + 't';
|
||||
EXPECT_FLOAT_EQ(test1.size(), 5);
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[0], 'a');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[1], 'a');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[2], 'h');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[3], 'e');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[4], 't');
|
||||
EXPECT_FLOAT_EQ(test1.c_str()[5], '\0');
|
||||
EXPECT_EQ(test1.size(), 5);
|
||||
EXPECT_EQ(test1.c_str()[0], 'a');
|
||||
EXPECT_EQ(test1.c_str()[1], 'a');
|
||||
EXPECT_EQ(test1.c_str()[2], 'h');
|
||||
EXPECT_EQ(test1.c_str()[3], 'e');
|
||||
EXPECT_EQ(test1.c_str()[4], 't');
|
||||
EXPECT_EQ(test1.c_str()[5], '\0');
|
||||
}
|
||||
|
@ -18,7 +18,17 @@ TEST(TestVector, constructor) {
|
||||
|
||||
TEST(TestVector, constructor_2) {
|
||||
// Test contructor value
|
||||
etk::Vector<float> test(3);
|
||||
etk::Vector<float> test(3.9f, 33.0f,55.8f);
|
||||
EXPECT_EQ(test.size(), 3);
|
||||
EXPECT_EQ(test[0], 3.9f);
|
||||
EXPECT_EQ(test[1], 33.0f);
|
||||
EXPECT_EQ(test[2], 55.8f);
|
||||
}
|
||||
|
||||
TEST(TestVector, resize) {
|
||||
// Test contructor value
|
||||
etk::Vector<float> test;
|
||||
test.resize(3);
|
||||
EXPECT_EQ(test.size(), 3);
|
||||
}
|
||||
TEST(TestVector, empty) {
|
||||
@ -182,3 +192,83 @@ TEST(TestVector, initializationList_2) {
|
||||
EXPECT_EQ(test[3], 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint32_t isDestroy = 0;
|
||||
|
||||
class testContructDestruct {
|
||||
private:
|
||||
uint32_t m_addValue;
|
||||
public:
|
||||
testContructDestruct(uint32_t _addValue):
|
||||
m_addValue(_addValue) {
|
||||
isDestroy += m_addValue;
|
||||
TEST_DEBUG("Create class " << m_addValue);
|
||||
}
|
||||
testContructDestruct(testContructDestruct&& _obj):
|
||||
m_addValue(_obj.m_addValue) {
|
||||
_obj.m_addValue = 0;
|
||||
TEST_DEBUG("move contruction " << m_addValue);
|
||||
}
|
||||
virtual ~testContructDestruct() {
|
||||
if (m_addValue == 0) {
|
||||
TEST_DEBUG("Remove class (after move)");
|
||||
return;
|
||||
}
|
||||
TEST_DEBUG("Remove Class " << m_addValue);
|
||||
isDestroy -= m_addValue;
|
||||
}
|
||||
testContructDestruct& operator= (testContructDestruct&& _obj) {
|
||||
TEST_DEBUG("move operator " << m_addValue);
|
||||
if (this != &_obj) {
|
||||
etk::swap(m_addValue, _obj.m_addValue);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(TestVector, destroyElementAtTheCorectMoment) {
|
||||
isDestroy = 0;
|
||||
{
|
||||
etk::Vector<testContructDestruct> list;
|
||||
list.pushBack(testContructDestruct(55));
|
||||
EXPECT_EQ(list.size(), 1);
|
||||
EXPECT_EQ(isDestroy, 55);
|
||||
auto it = list.erase(list.begin());
|
||||
EXPECT_EQ(isDestroy, 0);
|
||||
EXPECT_EQ(list.size(), 0);
|
||||
EXPECT_EQ(it, list.end());
|
||||
}
|
||||
EXPECT_EQ(isDestroy, 0);
|
||||
}
|
||||
|
||||
TEST(TestVector, destroyElementAtTheCorectMoment_2) {
|
||||
isDestroy = 0;
|
||||
{
|
||||
etk::Vector<testContructDestruct> list;
|
||||
list.pushBack(testContructDestruct(4));
|
||||
list.pushBack(testContructDestruct(30));
|
||||
list.pushBack(testContructDestruct(1000));
|
||||
list.pushBack(testContructDestruct(200));
|
||||
EXPECT_EQ(list.size(), 4);
|
||||
EXPECT_EQ(isDestroy, 1234);
|
||||
auto it = list.erase(list.begin());
|
||||
EXPECT_EQ(list.size(), 3);
|
||||
EXPECT_EQ(isDestroy, 1230);
|
||||
it = list.erase(list.begin()+1);
|
||||
EXPECT_EQ(isDestroy, 230);
|
||||
EXPECT_EQ(list.size(), 2);
|
||||
}
|
||||
EXPECT_EQ(isDestroy, 0);
|
||||
}
|
||||
|
||||
TEST(TestVector, allocateElementAtTheCorectMoment) {
|
||||
isDestroy = 0;
|
||||
{
|
||||
etk::Vector<testContructDestruct> list;
|
||||
list.reserve(10);
|
||||
EXPECT_EQ(list.size(), 0);
|
||||
EXPECT_EQ(isDestroy, 0);
|
||||
}
|
||||
EXPECT_EQ(isDestroy, 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user