Serious-Engine/Sources/Engine/Templates/StaticStackArray.cpp
2016-03-29 12:51:33 -04:00

189 lines
4.5 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#ifndef SE_INCL_STATICSTACKARRAY_CPP
#define SE_INCL_STATICSTACKARRAY_CPP
#ifdef PRAGMA_ONCE
#pragma once
#endif
#include <Engine/Templates/StaticStackArray.h>
#include <Engine/Templates/StaticArray.cpp>
/*
* Default constructor.
*/
template<class Type>
inline CStaticStackArray<Type>::CStaticStackArray(void) : CStaticArray<Type>() {
sa_UsedCount=0;
sa_ctAllocationStep = 256;
}
/*
* Destructor.
*/
template<class Type>
inline CStaticStackArray<Type>::~CStaticStackArray(void) {
};
/* Destroy all objects, and reset the array to initial (empty) state. */
template<class Type>
inline void CStaticStackArray<Type>::Clear(void) {
if (CStaticArray<Type>::Count()!=0) Delete();
}
/*
* Set how many elements to allocate when stack overflows.
*/
template<class Type>
inline void CStaticStackArray<Type>::SetAllocationStep(INDEX ctStep)
{
ASSERT(ctStep>0);
sa_ctAllocationStep = ctStep;
};
/*
* Create a given number of objects.
*/
template<class Type>
inline void CStaticStackArray<Type>::New(INDEX iCount) {
CStaticArray<Type>::New(iCount);
sa_UsedCount = 0;
};
/*
* Destroy all objects.
*/
template<class Type>
inline void CStaticStackArray<Type>::Delete(void) {
CStaticArray<Type>::Delete();
sa_UsedCount = 0;
}
/*
* Add new object(s) on top of stack.
*/
template<class Type>
inline Type &CStaticStackArray<Type>::Push(void) {
sa_UsedCount++;
if (sa_UsedCount>CStaticArray<Type>::Count()) {
this->Expand(CStaticArray<Type>::Count()+sa_ctAllocationStep);
}
ASSERT(sa_UsedCount <= CStaticArray<Type>::Count());
return CStaticArray<Type>::operator[](sa_UsedCount-1);
}
template<class Type>
inline Type *CStaticStackArray<Type>::Push(INDEX ct) {
sa_UsedCount+=ct;
while(sa_UsedCount>CStaticArray<Type>::Count()) {
Expand(CStaticArray<Type>::Count()+sa_ctAllocationStep);
}
ASSERT(sa_UsedCount <= CStaticArray<Type>::Count());
return &CStaticArray<Type>::operator[](sa_UsedCount-ct);
}
/* Remove one object from top of stack and return it. */
template<class Type>
inline Type &CStaticStackArray<Type>::Pop(void)
{
ASSERT(sa_UsedCount>0);
sa_UsedCount--;
return CStaticArray<Type>::operator[](sa_UsedCount);
}
/*
* Remove objects higher than the given index from stack, but keep stack space.
*/
template<class Type>
inline void CStaticStackArray<Type>::PopUntil(INDEX iNewTop)
{
ASSERT(iNewTop < sa_UsedCount);
sa_UsedCount = iNewTop+1;
}
/*
* Remove all objects from stack, but keep stack space.
*/
template<class Type>
inline void CStaticStackArray<Type>::PopAll(void) {
sa_UsedCount = 0;
}
/*
* Random access operator.
*/
template<class Type>
inline Type &CStaticStackArray<Type>::operator[](INDEX i) {
ASSERT(this!=NULL);
ASSERT(i<sa_UsedCount); // check bounds
return CStaticArray<Type>::operator[](i);
}
template<class Type>
inline const Type &CStaticStackArray<Type>::operator[](INDEX i) const {
ASSERT(this!=NULL);
ASSERT(i<sa_UsedCount); // check bounds
return CStaticArray<Type>::operator[](i);
}
/*
* Get number of elements in array.
*/
template<class Type>
INDEX CStaticStackArray<Type>::Count(void) const {
ASSERT(this!=NULL);
return sa_UsedCount;
}
/*
* Get index of a member from it's pointer
*/
template<class Type>
INDEX CStaticStackArray<Type>::Index(Type *ptMember) {
ASSERT(this!=NULL);
INDEX i = CStaticArray<Type>::Index(ptMember);
ASSERTMSG(i<sa_UsedCount, "CStaticStackArray<>::Index(): Not a member of this array!");
return i;
}
/*
* Assignment operator.
*/
template<class Type>
CStaticStackArray<Type> &CStaticStackArray<Type>::operator=(const CStaticStackArray<Type> &arOriginal)
{
ASSERT(this!=NULL);
ASSERT(&arOriginal!=NULL);
ASSERT(this!=&arOriginal);
// copy stack arrays
CStaticArray<Type>::operator=(arOriginal);
// copy used count
sa_UsedCount = arOriginal.sa_UsedCount;
return *this;
}
/* Move all elements of another array into this one. */
template<class Type>
void CStaticStackArray<Type>::MoveArray(CStaticStackArray<Type> &arOther)
{
ASSERT(this!=NULL);
ASSERT(&arOther!=NULL);
ASSERT(this!=&arOther);
// clear previous contents
Clear();
// if the other array has no elements
if (arOther.Count()==0) {
// no assignment
return;
}
// move data from the other array into this one and clear the other one
CStaticArray<Type>::MoveArray(arOther);
sa_UsedCount = arOther.sa_UsedCount ;
sa_ctAllocationStep = arOther.sa_ctAllocationStep ;
arOther.sa_UsedCount = 0;
}
#endif /* include-once check. */