/* ************************************************************************* ArmageTron -- Just another Tron Lightcycle Game in 3D. Copyright (C) 2000 Manuel Moos (manuel@moosnet.de) ************************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *************************************************************************** */ #ifndef ArmageTron_ARRAY_H #define ArmageTron_ARRAY_H #include "defs.h" #include #include "tError.h" #include "tSafePTR.h" class GrowingArrayBase { int len; // current logical size int size; // current size in memory void *base; // start of memory block const GrowingArrayBase & operator=(const GrowingArrayBase &); GrowingArrayBase(GrowingArrayBase &); protected: void ResizeBase(int i,int size_of_T, bool useMalloc); void *Base() const {return base;} GrowingArrayBase(int firstsize,int size_of_T, bool useMalloc); void Delete( bool useMalloc ); ~GrowingArrayBase(); /* #ifdef tSAFEPTR void SetSize(int s){size=s;} void SetBase(void *b){base=b;} #endif */ public: void ComplainIfFull(); void SetLen(int i){len=i;} int Len()const {return len;} int Size() const {return size;} }; template class tArray: public GrowingArrayBase { protected: void Init(){ int i; for(i=Size()-1;i>=0;i--) new(reinterpret_cast(Base())+i) T(); } void resize(int i){ int oldsize=Size(); ResizeBase(i,sizeof(T),MALLOC); // dump(low,flow,"Array resize from " << oldsize << " to " << Size()); for(i=Size()-1;i>=oldsize;i--) new(reinterpret_cast(Base())+i) T(); } void Clear(){ int i; for(i=Size()-1;i>=0;i--){ // dump(low,flow,"i=" << i); ((reinterpret_cast(Base()))+i)->~T(); } Delete(MALLOC); } void CopyFrom(const tArray &A){ int i; for(i=Len()-1;i>=0;i--) new(reinterpret_cast(Base())+i) T(A(i)); for(i=Len();i(Base())+i) T(); } public: void SetLen(int i){ GrowingArrayBase::SetLen(i); if (i>Size()) resize(i); } ~tArray(){ tERR_FLOW_LOW(); Clear(); Delete(MALLOC); } tArray(int firstsize=0) :GrowingArrayBase(firstsize,sizeof(T),MALLOC) { // dump(low,flow,"con:size " << firstsize); Init(); }; tArray(const tArray &A) :GrowingArrayBase(A.Len(),sizeof(T),MALLOC){ CopyFrom(A); }; T& operator[](int i) { #ifdef DEBUG if (i<0) { tERR_ERROR_INT("Range error;accesed negative element " << i ); } #endif if (i>=Len()) SetLen(i+1); // dump(low,flow,"[" << i << "]" << "=" << ((T *)Base())[i] << '\n'); return((reinterpret_cast(Base()))[i]); }; T& operator()(int i) const{ tASSERT( i >= 0 && i < Len() ); return((reinterpret_cast(Base()))[i]); }; T* operator+(int i) const{ #ifdef DEBUG if (i<0) {tERR_ERROR_INT("Range error;accesed negative element " << i )} if (i>=Len()) {tERR_ERROR_INT("Range error;accesed element " << i <<" of maximal " <(Base())+i); }; const tArray &operator=(const tArray &A){ SetLen(A.Len()); Clear(); CopyFrom(A); return *this; }; void RemoveAt( int index ) { int newLen = this->Len()-1; T keep = (*this)[ index ]; if ( index < newLen ) (*this)[ index ] = (*this)[ newLen ]; this->SetLen( newLen ); } bool Remove( const T& t ) { for ( int i = this->Len()-1; i >= 0; --i ) { if ( (*this)[i] == t ) { this->RemoveAt( i ); return true; } } return false; } void Insert( const T& t ) { SetLen( this->Len()+1 ); (*this)[ this->Len() -1 ] = t; } }; #endif // _ARRAY_H_