Serious-Engine/Sources/Engine/Templates/DynamicStackArray.cpp
Ryan C. Gordon 24cb244d43 First attempt to hand-merge Ryan's Linux and Mac OS X port.
This was a _ton_ of changes, made 15 years ago, so there are probably some
problems to work out still.

Among others: Engine/Base/Stream.* was mostly abandoned and will need to be
re-ported.

Still, this is a pretty good start, and probably holds a world record for
lines of changes or something.  :)
2016-03-28 23:46:13 -04:00

165 lines
4.1 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#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()) {
// 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;
}
/*
* 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. */