#ifndef VECTOR_HPP_ #define VECTOR_HPP_ #include #include // allocation block size // size of allocated memory will usually be a multiple of this #define CVECTOR_BLOCKSIZE 10 extern i32 g_poolId; // vector class template template class CVector { protected: // number of elements in vector unsigned int m_numElements; // size of allocated buffer unsigned int m_bufferSize; // pointer to buffer dataT* m_buffer; public: // default constructor CVector() : m_numElements(0), m_bufferSize(0), m_buffer(0) {} // constructor with size and init value CVector(unsigned int argSize, const dataT& val = dataT()) : m_numElements(0), m_bufferSize(0), m_buffer(0) { resize(argSize, val); } // destructor virtual ~CVector() { clear(); } // copy operator for CVector CVector& operator=(const CVector& copyVector) { // check assignment to self if (this == ©Vector) return *this; // get new size unsigned int newSize = copyVector.size(); if (newSize > m_bufferSize) { // reserve new buffer reserve(newSize); // if buffer is OK, copy each element of vector if (m_bufferSize >= newSize) { for (int i = 0; i < newSize; i++) m_buffer[i] = copyVector.m_buffer[i]; m_numElements = newSize; } } return *this; } // operator=() // reserve buffer size for vector void reserve(unsigned int argSize) { dataT* tmpPtr; // calculate new buffer size as multiple of CVECTOR_BLOCKSIZE unsigned int newBufferSize = ((argSize + CVECTOR_BLOCKSIZE - 1) / CVECTOR_BLOCKSIZE) * CVECTOR_BLOCKSIZE; if (newBufferSize > m_bufferSize) { // if the new size is larger than the old // allocate new memory // allocate one additional element as end element if (g_poolId > 0) // take from memory pool { tmpPtr = new(g_poolId) dataT[newBufferSize + 1]; } else { // take from heap tmpPtr = new dataT[newBufferSize + 1]; } if (tmpPtr) { // copy old buffer to new buffer std::memcpy(tmpPtr, m_buffer, m_numElements * sizeof(dataT)); // clear copied buffer area, so that we can delete it (this calls the destructors, which should do nothing). std::memset(m_buffer, 0, m_numElements * sizeof(dataT)); // delete old buffer delete [] m_buffer; // set buffer pointer and size m_buffer = tmpPtr; m_bufferSize = newBufferSize; } else { AaSysLogPrint(EAaSysLogSeverityLevel_Error, "allocate heap failed.g_poolId : %x", g_poolId); } } // if (newBufferSize > m_bufferSize) } // reserve() unsigned int size() const { return m_numElements; } unsigned int capacity() const { return m_bufferSize; } dataT* begin() const { return m_buffer; } // begin() dataT* end() const { if (m_buffer) return m_buffer + m_numElements; else return 0; } // end() dataT& front() { return m_buffer[0]; } const dataT& front() const { return m_buffer[0]; } dataT& back() { return m_buffer[m_numElements - 1]; } const dataT& back() const { return m_buffer[m_numElements - 1]; } // add element at end of vector void push_back(const dataT& data = dataT()) { // if buffer is too small for additional element, // allocate new buffer if (m_numElements + 1 > m_bufferSize) reserve(m_numElements + 1); // if the buffer is now large enough if (m_numElements + 1 <= m_bufferSize) { // add new element as last element m_buffer[m_numElements] = data; // increment number of elements m_numElements++; } } // push_back() // remove last element from vector void pop_back() { if (m_numElements > 0) { m_numElements--; } } // pop_back() dataT& operator[](unsigned int index) { return m_buffer[index]; } const dataT& operator[](unsigned int index) const { return m_buffer[index]; } // resize vector void resize(unsigned int argSize, const dataT& val = dataT()) { // if the new size is smaller than the old size // we leave the content and just set the new size if (argSize <= m_numElements) { m_numElements = argSize; } // if the new size is larger than the old size, // but smaller than the allocated buffer, // we initialize all newly created elements to val and // set the new vector size else if (argSize <= m_bufferSize) { // initialize new buffer area to data for (int i = m_numElements; i < argSize; i++) m_buffer[i] = val; m_numElements = argSize; } // if the buffer is too small for the new size, // we enlarge the buffer and then set all newly // created elements to val else { // reserve a larger buffer reserve(argSize); if (argSize <= m_bufferSize) { // initialize new buffer area to data for (int i = m_numElements; i < argSize; i++) m_buffer[i] = val; m_numElements = argSize; } } } // resize() void clear() { // free buffer memory, calls destructor for each element if (m_buffer) delete [] m_buffer; m_buffer = 0; m_numElements = 0; m_bufferSize = 0; } }; // class CVector #endif /*VECTOR_HPP_*/