205 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			205 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #ifndef HX_QUICKVEC_INCLUDED
 | ||
|  | #define HX_QUICKVEC_INCLUDED
 | ||
|  | 
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include <algorithm>
 | ||
|  | 
 | ||
|  | namespace hx | ||
|  | { | ||
|  | 
 | ||
|  | template<typename T> | ||
|  | struct QuickVec | ||
|  | { | ||
|  |    int mAlloc; | ||
|  |    int mSize; | ||
|  |    T *mPtr; | ||
|  | 
 | ||
|  |    QuickVec() : mPtr(0), mAlloc(0), mSize(0) { }  | ||
|  |    ~QuickVec() | ||
|  |    { | ||
|  |       if (mPtr) | ||
|  |          free(mPtr); | ||
|  |    } | ||
|  | 
 | ||
|  |    inline void push(const T &inT) | ||
|  |    { | ||
|  |       if (mSize+1>mAlloc) | ||
|  |       { | ||
|  |          mAlloc = 10 + (mSize*3/2); | ||
|  |          mPtr = (T *)realloc(mPtr,sizeof(T)*mAlloc); | ||
|  |       } | ||
|  |       mPtr[mSize]=inT; | ||
|  |       mSize++; | ||
|  |    } | ||
|  |    void swap(QuickVec<T> &inOther) | ||
|  |    { | ||
|  |       std::swap(mAlloc, inOther.mAlloc); | ||
|  |       std::swap(mSize, inOther.mSize); | ||
|  |       std::swap(mPtr, inOther.mPtr); | ||
|  |    } | ||
|  |    T *setSize(int inSize) | ||
|  |    { | ||
|  |       if (inSize>mAlloc) | ||
|  |       { | ||
|  |          mAlloc = inSize; | ||
|  |          mPtr = (T *)realloc(mPtr,sizeof(T)*mAlloc); | ||
|  |       } | ||
|  |       mSize = inSize; | ||
|  |       return mPtr; | ||
|  |    } | ||
|  |    // Can push this many without realloc
 | ||
|  |    bool hasExtraCapacity(int inN) | ||
|  |    { | ||
|  |       return mSize+inN<=mAlloc; | ||
|  |    } | ||
|  | 
 | ||
|  |    bool safeReserveExtra(int inN) | ||
|  |    { | ||
|  |       int want = mSize + inN; | ||
|  |       if (want>mAlloc) | ||
|  |       { | ||
|  |          int wantAlloc = 10 + (mSize*3/2); | ||
|  |          if (wantAlloc<want) | ||
|  |             wantAlloc = want; | ||
|  |          T *newBuffer = (T *)malloc( sizeof(T)*wantAlloc ); | ||
|  |          if (!newBuffer) | ||
|  |             return false; | ||
|  |          mAlloc = wantAlloc; | ||
|  |          if (mPtr) | ||
|  |          { | ||
|  |             memcpy(newBuffer, mPtr, mSize*sizeof(T)); | ||
|  |             free(mPtr); | ||
|  |          } | ||
|  |          mPtr = newBuffer; | ||
|  |       } | ||
|  |       return true; | ||
|  |    } | ||
|  |    inline void pop_back() { --mSize; } | ||
|  |    inline T &back() { return mPtr[mSize-1]; } | ||
|  |    inline T pop() | ||
|  |    { | ||
|  |       return mPtr[--mSize]; | ||
|  |    } | ||
|  |    inline void qerase(int inPos) | ||
|  |    { | ||
|  |       --mSize; | ||
|  |       mPtr[inPos] = mPtr[mSize]; | ||
|  |    } | ||
|  |    inline void erase(int inPos) | ||
|  |    { | ||
|  |       --mSize; | ||
|  |       if (mSize>inPos) | ||
|  |          memmove(mPtr+inPos, mPtr+inPos+1, (mSize-inPos)*sizeof(T)); | ||
|  |    } | ||
|  |    void zero() { memset(mPtr,0,mSize*sizeof(T) ); } | ||
|  | 
 | ||
|  |    inline bool qerase_val(T inVal) | ||
|  |    { | ||
|  |       for(int i=0;i<mSize;i++) | ||
|  |          if (mPtr[i]==inVal) | ||
|  |          { | ||
|  |             --mSize; | ||
|  |             mPtr[i] = mPtr[mSize]; | ||
|  |             return true; | ||
|  |          } | ||
|  |       return false; | ||
|  |    } | ||
|  | 
 | ||
|  |    inline bool some_left() { return mSize; } | ||
|  |    inline bool empty() const { return !mSize; } | ||
|  |    inline void clear() { mSize = 0; } | ||
|  |    inline int next() | ||
|  |    { | ||
|  |       if (mSize+1>=mAlloc) | ||
|  |       { | ||
|  |          mAlloc = 10 + (mSize*3/2); | ||
|  |          mPtr = (T *)realloc(mPtr,sizeof(T)*mAlloc); | ||
|  |       } | ||
|  |       return mSize++; | ||
|  |    } | ||
|  |    inline int size() const { return mSize; } | ||
|  |    inline T &operator[](int inIndex) { return mPtr[inIndex]; } | ||
|  |    inline const T &operator[](int inIndex) const { return mPtr[inIndex]; } | ||
|  | 
 | ||
|  | private: | ||
|  |    QuickVec(const QuickVec<T> &); | ||
|  |    void operator =(const QuickVec<T> &); | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | template<typename T> | ||
|  | class QuickDeque | ||
|  | { | ||
|  |     struct Slab | ||
|  |     { | ||
|  |        T mElems[1024]; | ||
|  |     }; | ||
|  | 
 | ||
|  |     QuickVec<Slab *> mSpare; | ||
|  |     QuickVec<Slab *> mActive; | ||
|  | 
 | ||
|  |     int  mHeadPos; | ||
|  |     int  mTailPos; | ||
|  |     Slab *mHead; | ||
|  |     Slab *mTail; | ||
|  | 
 | ||
|  | public: | ||
|  | 
 | ||
|  |    QuickDeque() | ||
|  |    { | ||
|  |       mHead = mTail = 0; | ||
|  |       mHeadPos = 1024; | ||
|  |       mTailPos = 1024; | ||
|  |    } | ||
|  |    ~QuickDeque() | ||
|  |    { | ||
|  |       for(int i=0;i<mSpare.size();i++) | ||
|  |          delete mSpare[i]; | ||
|  |       for(int i=0;i<mActive.size();i++) | ||
|  |          delete mActive[i]; | ||
|  |       delete mHead; | ||
|  |       if (mTail!=mHead) | ||
|  |          delete mTail; | ||
|  |    } | ||
|  |    inline void push(T inObj) | ||
|  |    { | ||
|  |       if (mHeadPos<1024) | ||
|  |       { | ||
|  |          mHead->mElems[mHeadPos++] = inObj; | ||
|  |          return; | ||
|  |       } | ||
|  |       if (mHead != mTail) | ||
|  |          mActive.push(mHead); | ||
|  |       mHead = mSpare.empty() ? new Slab : mSpare.pop(); | ||
|  |       mHead->mElems[0] = inObj; | ||
|  |       mHeadPos = 1; | ||
|  |    } | ||
|  |    inline bool some_left() { return mHead!=mTail || mHeadPos!=mTailPos; } | ||
|  |    inline T pop() | ||
|  |    { | ||
|  |       if (mTailPos<1024) | ||
|  |          return mTail->mElems[mTailPos++]; | ||
|  |       if (mTail) | ||
|  |          mSpare.push(mTail); | ||
|  |       if (mActive.empty()) | ||
|  |       { | ||
|  |          mTail = mHead; | ||
|  |       } | ||
|  |       else | ||
|  |       { | ||
|  |          mTail = mActive[0]; | ||
|  |          mActive.erase(0); | ||
|  |       } | ||
|  |       mTailPos = 1; | ||
|  |       return mTail->mElems[0]; | ||
|  |    } | ||
|  | 
 | ||
|  | private: | ||
|  |    QuickDeque(const QuickDeque<T> &); | ||
|  |    void operator=(const QuickDeque<T> &); | ||
|  | }; | ||
|  | 
 | ||
|  | } // end namespace hx
 | ||
|  | 
 | ||
|  | #endif
 |