//************************************************************************************************* //************************************************************************************************* // // XArray // // Developed by jief666, from 1997. // //************************************************************************************************* //************************************************************************************************* #if !defined(__XARRAY_H__) #define __XARRAY_H__ #include "XToolsCommon.h" #if 0 #define XArray_DBG(...) DebugLog(2, __VA_ARGS__) #else #define XArray_DBG(...) #endif template class XArray { protected: TYPE *m_data; xsize m_len; xsize m_allocatedSize; xsize _GrowBy; public: void Init(); XArray() { Init(); } XArray(const XArray &anArray); const XArray &operator =(const XArray &anArray); virtual ~XArray(); public: const TYPE *data() const { return m_data; } TYPE *data() { return m_data; } public: xsize allocatedSize() const { return m_allocatedSize; } xsize length() const { return m_len; } xsize size() const { return m_len; } void setSize(xsize l); //low case functions like in std::vector const TYPE& begin() const { return ElementAt(0); } TYPE& begin() { return ElementAt(0); } const TYPE& end() const { return ElementAt(m_len - 1); } TYPE& end() { return ElementAt(m_len - 1); } xsize insert(const TYPE newElement, xsize pos, xsize count = 1) { return Insert(newElement, pos, count); } //-------------------------------------------------- const TYPE& ElementAt(xsize nIndex) const; TYPE& ElementAt(xsize nIndex); const TYPE& ElementAt(int nIndex) const; TYPE& ElementAt(int nIndex); const TYPE& operator[](xsize nIndex) const { return ElementAt(nIndex); } TYPE& operator[](xsize nIndex) { return ElementAt(nIndex); } const TYPE& operator[]( int nIndex) const { return ElementAt(nIndex); } TYPE& operator[]( int nIndex) { return ElementAt(nIndex); } operator const void *() const { return m_data; }; operator void *() { return m_data; }; operator const TYPE *() const { return m_data; }; operator TYPE *() { return m_data; }; const TYPE * operator +( int i) const { return m_data+i; }; TYPE * operator +( int i) { return m_data+i; }; const TYPE * operator +(xsize i) const { return m_data+i; }; TYPE * operator +(xsize i) { return m_data+i; }; const TYPE * operator -( int i) const { return m_data-i; }; TYPE * operator -( int i) { return m_data-i; }; const TYPE * operator -(xsize i) const { return m_data-i; }; TYPE * operator -(xsize i) { return m_data-i; }; // xsize Add(const TYPE newElement); // TYPE AddNew(); // xsize Inserts(const TYPE &newElement, xsize pos, xsize count); void CheckSize(xsize nNewSize); void CheckSize(xsize nNewSize, xsize nGrowBy); xsize AddUninitialized(xsize count); // add count uninitialzed elements xsize Add(const TYPE newElement, xsize count = 1); xsize AddArray(const TYPE *newElements, xsize count = 1); xsize Insert(const TYPE newElement, xsize pos, xsize count = 1); void Remove(const TYPE *Element); void Remove(const TYPE &Element); void RemoveAtIndex(xsize nIndex); void RemoveAtIndex(int nIndex); void setEmpty(); bool isEmpty() const { return size() == 0; } xsize IdxOf(TYPE& e) const; bool ExistIn(TYPE& e) const { return IdxOf(e) != MAX_XSIZE; } //logically it should be named as Contains(e) }; //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // // XArray // //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx template xsize XArray::IdxOf(TYPE& e) const { xsize i; for ( i=0 ; i void XArray::Init() { m_data = nullptr; m_allocatedSize = 0; m_len = 0; _GrowBy = XArrayGrowByDefault; } /* Constructeur */ template XArray::XArray(const XArray &anArray) { Init(); AddArray(anArray.data(), anArray.size()); } /* operator = */ template const XArray &XArray::operator =(const XArray &anArray) { if ( anArray.length() > 0 ) { CheckSize(anArray.length(), 0); memcpy(m_data, anArray.m_data, anArray.m_len * sizeof(TYPE)); m_len = anArray.m_len; } else { setEmpty(); } // // //xsize ui; // // setEmpty(); // for ( ui=0 ; ui XArray::~XArray() { //printf("XArray Destructor\n"); if ( m_data ) free(m_data); } /* CheckSize() */ template void XArray::CheckSize(xsize nNewSize, xsize nGrowBy) { //XArray_DBG("CheckSize: m_len=%d, m_size=%d, nGrowBy=%d, nNewSize=%d\n", m_len, m_size, nGrowBy, nNewSize); if ( nNewSize > m_allocatedSize ) { nNewSize += nGrowBy; m_data = (TYPE *)realloc((void *)m_data, nNewSize * sizeof(TYPE), m_allocatedSize * sizeof(TYPE) ); if ( !m_data ) { DebugLog(2, "XArray::CheckSize(nNewSize=%llu, nGrowBy=%llu) : Xrealloc(%llu, %llu, %" PRIuPTR ") returned NULL. System halted\n", nNewSize, nGrowBy, m_allocatedSize, nNewSize*sizeof(TYPE), (uintptr_t)m_data); panic(); } // memset(&_Data[_Size], 0, (nNewSize-_Size) * sizeof(TYPE)); // Could help for debugging, but zeroing in not needed. m_allocatedSize = nNewSize; } } /* CheckSize() */ template void XArray::CheckSize(xsize nNewSize) { CheckSize(nNewSize, XArrayGrowByDefault); } /* SetLength (xsize i) */ template void XArray::setSize(xsize l) { CheckSize(l, XArrayGrowByDefault); // be sure the size is allocated m_len = l; #ifdef DEBUG if(m_len > m_allocatedSize) { DebugLog(2, "XArray::SetLength(xsize) -> _Len > _Size"); panic(); } #endif } /* ElementAt() */ template TYPE &XArray::ElementAt(xsize index) { // #ifdef _DEBUG if ( index >= m_len ) { DebugLog(2, "XArray::ElementAt(xsize) -> Operator [] : index > m_len"); panic(); } // #endif return m_data[index]; } /* ElementAt() */ template const TYPE& XArray::ElementAt(xsize index) const { // #ifdef _DEBUG if ( index >= m_len ) { DebugLog(2, "XArray::ElementAt(xsize) const -> Operator [] : index > m_len"); panic(); } // #endif return m_data[index]; } /* ElementAt() */ template TYPE &XArray::ElementAt(int index) { // #ifdef _DEBUG if ( index < 0 ) { panic("XArray::ElementAt(int) -> Operator [] : index < 0"); } if ( (unsigned int)index >= m_len ) { // cast safe, index > 0 DebugLog(2, "XArray::ElementAt(int) -> Operator [] : index > m_len"); panic(); } // #endif return m_data[index]; } /* ElementAt() */ template const TYPE& XArray::ElementAt(int index) const { // #ifdef _DEBUG if ( index < 0 ) { panic("XArray::ElementAt(int) const -> Operator [] : index < 0"); } if ( (unsigned int)index >= m_len ) { // cast ok as index > 0. Ideally cast would be like '(unsigned __typeof__(index))' DebugLog(2, "XArray::ElementAt(int) const -> Operator [] : index > m_len"); panic(); } // #endif return m_data[index]; } /* Add(xsize) */ template xsize XArray::AddUninitialized(xsize count) { CheckSize(m_len+count); m_len += count; return m_len-count; } /* Add(TYPE, xsize) */ template xsize XArray::Add(const TYPE newElement, xsize count) { // XArray_DBG("xsize XArray::Add(const TYPE newElement, xsize count) -> Enter. count=%d _Len=%d _Size=%d\n", count, m_len, m_size); xsize i; CheckSize(m_len+count); for ( i=0 ; i xsize XArray::AddArray(const TYPE *newElements, xsize count) { xsize i; CheckSize(m_len+count); for ( i=0 ; i xsize XArray::Insert(const TYPE newElement, xsize pos, xsize count) { xsize i; if ( pos < m_len ) { CheckSize(m_len+count); memmove(&m_data[pos], &m_data[pos+count], (m_len-pos)*sizeof(TYPE)); for ( i=0 ; i void XArray::RemoveAtIndex(xsize nIndex) { if ( nIndex < m_len ) { if ( nIndex nIndex > m_len\n"); #endif } /* Remove(int) */ template void XArray::RemoveAtIndex(int nIndex) { #if defined(__XTOOLS_INT_CHECK__) if ( nIndex < 0 ) { DebugLog(2, "XArray::RemoveAtIndex(int nIndex) : BUG nIndex (%d) is < 0. System halted\n", nIndex); panic(); } #endif RemoveAtIndex( (xsize)nIndex ); // Check of nIndex is made in Remove(xsize nIndex) return; } /* Remove(TYPE) */ template void XArray::Remove(const TYPE &Element) { xsize i; for ( i=0 ; i Element not found\n"); #endif } /* Remove(TYPE *) */ template void XArray::Remove(const TYPE *Element) { Remove(*Element); } /* Empty() */ template void XArray::setEmpty() { //printf("XArray Empty\n"); m_len = 0; } #endif