Serious-Engine/Sources/Engine/Templates/DynamicStackArray.cpp

178 lines
4.7 KiB
C++
Raw Normal View History

2016-03-12 01:20:51 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2016-03-11 14:57:17 +01:00
#ifndef SE_INCL_DYNAMICSTACKARRAY_CPP
#define SE_INCL_DYNAMICSTACKARRAY_CPP
#ifdef PRAGMA_ONCE
#pragma once
#endif
#include <Engine/Templates/DynamicStackArray.h>
#include <Engine/Templates/DynamicArray.cpp>
/*
* Default constructor.
*/
template<class Type>
inline CDynamicStackArray<Type>::CDynamicStackArray(void) : CDynamicArray<Type>() {
da_ctUsed=0;
da_ctAllocationStep = 256;
// lock the array on construction
CDynamicArray<Type>::Lock();
}
/*
* Destructor.
*/
template<class Type>
inline CDynamicStackArray<Type>::~CDynamicStackArray(void) {
// lock the array on destruction
CDynamicArray<Type>::Unlock();
};
/* Destroy all objects, and reset the array to initial (empty) state. */
template<class Type>
inline void CDynamicStackArray<Type>::Clear(void) {
CDynamicArray<Type>::Clear(); da_ctUsed = 0;
}
/*
* Set how many elements to allocate when stack overflows.
*/
template<class Type>
inline void CDynamicStackArray<Type>::SetAllocationStep(INDEX ctStep)
{
ASSERT(ctStep>0);
da_ctAllocationStep = ctStep;
};
/*
* Add new object(s) on top of stack.
*/
template<class Type>
inline Type &CDynamicStackArray<Type>::Push(void) {
// if there are no free elements in the array
if (CDynamicArray<Type>::Count()-da_ctUsed<1) {
// alocate a new block
CDynamicArray<Type>::New(da_ctAllocationStep);
}
// get the new element
da_ctUsed++;
ASSERT(da_ctUsed <= CDynamicArray<Type>::Count());
return CDynamicArray<Type>::operator[](da_ctUsed-1);
}
template<class Type>
inline Type *CDynamicStackArray<Type>::Push(INDEX ct) {
// if there are no free elements in the array
while(CDynamicArray<Type>::Count()-da_ctUsed<ct) {
// alocate a new block
CDynamicArray<Type>::New(da_ctAllocationStep);
}
// get new elements
da_ctUsed+=ct;
ASSERT(da_ctUsed <= CDynamicArray<Type>::Count());
return &CDynamicArray<Type>::operator[](da_ctUsed-ct);
}
/*
* Remove all objects from stack, but keep stack space.
*/
template<class Type>
inline void CDynamicStackArray<Type>::PopAll(void) {
// if there is only one block allocated
if ( this->da_BlocksList.IsEmpty()
|| &this->da_BlocksList.Head()==&this->da_BlocksList.Tail()) {
2016-03-11 14:57:17 +01:00
// just clear the counter
da_ctUsed = 0;
// if there is more than one block allocated
} else {
// remember how much was allocated, rounded up to allocation step
INDEX ctUsedBefore = CDynamicArray<Type>::Count();
// free all memory
CDynamicArray<Type>::Clear();
// allocate one big block
CDynamicArray<Type>::New(ctUsedBefore);
da_ctUsed = 0;
}
}
/*
* Random access operator.
*/
template<class Type>
inline Type &CDynamicStackArray<Type>::operator[](INDEX i) {
ASSERT(this!=NULL);
ASSERT(i<da_ctUsed); // check bounds
return CDynamicArray<Type>::operator[](i);
}
template<class Type>
inline const Type &CDynamicStackArray<Type>::operator[](INDEX i) const {
ASSERT(this!=NULL);
ASSERT(i<da_ctUsed); // check bounds
return CDynamicArray<Type>::operator[](i);
}
/*
* Get number of elements in array.
*/
template<class Type>
INDEX CDynamicStackArray<Type>::Count(void) const {
ASSERT(this!=NULL);
return da_ctUsed;
}
/*
* Get index of a member from it's pointer
*/
template<class Type>
INDEX CDynamicStackArray<Type>::Index(Type *ptMember) {
ASSERT(this!=NULL);
INDEX i = CDynamicArray<Type>::Index(ptMember);
ASSERTMSG(i<da_ctUsed, "CDynamicStackArray<>::Index(): Not a member of this array!");
return i;
}
/*
* Get array of pointers to elements (used for sorting elements by sorting pointers).
*/
template<class Type>
Type **CDynamicStackArray<Type>::GetArrayOfPointers(void)
{
return this->da_Pointers;
2016-03-11 14:57:17 +01:00
}
/*
* Assignment operator.
*/
template<class Type>
CDynamicStackArray<Type> &CDynamicStackArray<Type>::operator=(CDynamicStackArray<Type> &arOriginal)
{
ASSERT(this!=NULL);
ASSERT(&arOriginal!=NULL);
ASSERT(this!=&arOriginal);
// copy stack arrays
CDynamicArray<Type>::operator=(arOriginal);
// copy used count
da_ctUsed = arOriginal.da_ctUsed;
return *this;
}
#endif /* include-once check. */