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
 |