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
 |