📄 narray.h
字号:
else
{
// this is a forward move
int i;
for (i = num - 1; i >= 0; --i)
{
this->elements[toIndex + i] = this->elements[fromIndex + i];
}
// destroy freed elements
for (i = fromIndex; i < toIndex; i++)
{
this->Destroy(&(this->elements[i]));
}
}
// adjust array size
this->numElements = toIndex + num;
}
//------------------------------------------------------------------------------
/**
Very fast move which does not call assignment operators or destructors,
so you better know what you do!
*/
template<class TYPE>
void
nArray<TYPE>::MoveQuick(int fromIndex, int toIndex)
{
ASSERT(this->elements);
ASSERT(fromIndex < this->numElements);
// compute number of elements to move
int num = this->numElements - fromIndex;
// nothing to move?
if (fromIndex == toIndex)
{
return;
}
// do a direct memory move
memmove(&(this->elements[toIndex]), &(this->elements[fromIndex]), num * sizeof(TYPE));
// adjust array size
this->numElements = toIndex + num;
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
TYPE&
nArray<TYPE>::PushBack(const TYPE& elm)
{
// grow allocated space if exhausted
if (this->numElements == this->allocSize)
{
this->Grow();
}
ASSERT(this->elements);
this->elements[this->numElements] = elm;
return this->elements[this->numElements++];
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
void
nArray<TYPE>::Append(const TYPE& elm)
{
// grow allocated space if exhausted
if (this->numElements == this->allocSize)
{
this->Grow();
}
ASSERT(this->elements);
this->elements[this->numElements++] = elm;
}
//------------------------------------------------------------------------------
/**
Make room for N new elements at the end of the array, and return a pointer
to the start of the reserved area. This can be (carefully!) used as a fast
shortcut to fill the array directly with data.
*/
template<class TYPE>
typename nArray<TYPE>::iterator
nArray<TYPE>::Reserve(int num)
{
ASSERT(num > 0);
int maxElement = this->numElements + num;
while (maxElement >= this->allocSize)
{
this->Grow();
}
ASSERT(this->elements);
iterator iter = this->elements + this->numElements;
this->numElements += num;
return iter;
}
//------------------------------------------------------------------------------
/**
This will check if the provided index is in the valid range. If it is
not the array will be grown to that index.
*/
template<class TYPE>
void
nArray<TYPE>::CheckIndex(int index)
{
if (index >= this->numElements)
{
// grow array if necessary
if (index >= this->allocSize)
{
ASSERT(this->growSize > 0);
this->GrowTo(index + this->growSize);
}
// update number of contained elements
this->numElements = index + 1;
}
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
TYPE&
nArray<TYPE>::Set(int index, const TYPE& elm)
{
ASSERT(index < this->numElements);
this->CheckIndex(index);
this->elements[index] = elm;
return this->elements[index];
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
int
nArray<TYPE>::Size() const
{
return this->numElements;
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
int
nArray<TYPE>::AllocSize() const
{
return this->allocSize;
}
//------------------------------------------------------------------------------
/**
Access an element. This method may grow the array if the index is
outside the array range.
*/
template<class TYPE>
TYPE&
nArray<TYPE>::At(int index)
{
this->CheckIndex(index);
return this->elements[index];
}
//------------------------------------------------------------------------------
/**
Access an element. This method will NOT grow the array, and instead do
a range check, which may throw an assertion.
*/
template<class TYPE>
TYPE&
nArray<TYPE>::operator[](int index) const
{
ASSERT(this->elements && (index >= 0) && (index < this->numElements));
return this->elements[index];
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
TYPE&
nArray<TYPE>::Front() const
{
ASSERT(this->elements && (this->numElements > 0));
return this->elements[0];
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
TYPE&
nArray<TYPE>::Back() const
{
ASSERT(this->elements && (this->numElements > 0));
return this->elements[this->numElements - 1];
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
bool
nArray<TYPE>::Empty() const
{
return (this->numElements == 0);
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
void
nArray<TYPE>::Erase(int index)
{
ASSERT(this->elements && (index >= 0) && (index < this->numElements));
if (index == (this->numElements - 1))
{
// special case: last element
this->Destroy(&(this->elements[index]));
this->numElements--;
}
else
{
this->Move(index + 1, index);
}
}
//------------------------------------------------------------------------------
/**
Quick erase, uses memmove() and does not call assignment operators
or destructor, so be careful about that!
*/
template<class TYPE>
void
nArray<TYPE>::EraseQuick(int index)
{
ASSERT(this->elements && (index >= 0) && (index < this->numElements));
if (index == (this->numElements - 1))
{
// special case: last element
this->numElements--;
}
else
{
this->MoveQuick(index + 1, index);
}
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
typename nArray<TYPE>::iterator
nArray<TYPE>::Erase(typename nArray<TYPE>::iterator iter)
{
ASSERT(this->elements && (iter >= this->elements) && (iter < (this->elements + this->numElements)));
this->Erase(iter - this->elements);
return iter;
}
//------------------------------------------------------------------------------
/**
Quick erase, uses memmove() and does not call assignment operators
or destructor, so be careful about that!
*/
template<class TYPE>
typename nArray<TYPE>::iterator
nArray<TYPE>::EraseQuick(typename nArray<TYPE>::iterator iter)
{
ASSERT(this->elements && (iter >= this->elements) && (iter < (this->elements + this->numElements)));
this->EraseQuick(iter - this->elements);
return iter;
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
void
nArray<TYPE>::Insert(int index, const TYPE& elm)
{
ASSERT((index >= 0) && (index <= this->numElements));
if (index == this->numElements)
{
// special case: append element to back
this->PushBack(elm);
}
else
{
this->Move(index, index + 1);
this->elements[index] = elm;
}
}
//------------------------------------------------------------------------------
/**
The current implementation of this method does not shrink the
preallocated space. It simply sets the array size to 0.
*/
template<class TYPE>
void
nArray<TYPE>::Clear()
{
int i;
for (i = 0; i < this->numElements; i++)
{
this->Destroy(&(this->elements[i]));
}
this->numElements = 0;
}
//------------------------------------------------------------------------------
/**
This is identical with Clear(), but does NOT call destructors (it just
resets the numElements member. USE WITH CARE!
*/
template<class TYPE>
void
nArray<TYPE>::Reset()
{
this->numElements = 0;
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
typename nArray<TYPE>::iterator
nArray<TYPE>::Begin() const
{
return this->elements;
}
//------------------------------------------------------------------------------
/**
*/
template<class TYPE>
typename nArray<TYPE>::iterator
nArray<TYPE>::End() const
{
return this->elements + this->numElements;
}
//------------------------------------------------------------------------------
/**
Find element in array, return iterator, or 0 if element not
found.
@param elm element to find
@return element iterator, or 0 if not found
*/
template<class TYPE>
typename nArray<TYPE>::iterator
nArray<TYPE>::Find(const TYPE& elm) const
{
int index;
for (index = 0; index < this->numElements; index++)
{
if (this->elements[index] == elm)
{
return &(this->elements[index]);
}
}
return 0;
}
//------------------------------------------------------------------------------
/**
Find element in array, return element index, or -1 if element not
found.
@param elm element to find
@return index to element, or -1 if not found
*/
template<class TYPE>
int
nArray<TYPE>::FindIndex(const TYPE& elm) const
{
int index;
for (index = 0; index < this->numElements; index++)
{
if (this->elements[index] == elm)
{
return index;
}
}
return -1;
}
//------------------------------------------------------------------------------
/**
Fills an array range with the given element value. Will grow the
array if necessary
@param first index of first element to start fill
@param num num elements to fill
@param elm fill value
*/
template<class TYPE>
void
nArray<TYPE>::Fill(int first, int num, const TYPE& elm)
{
if ((first + num) > this->numElements)
{
this->GrowTo(first + num);
}
int i;
for (i = first; i < (first + num); i++)
{
this->elements[i] = elm;
}
}
//------------------------------------------------------------------------------
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -