Initial commit.
This commit is contained in:
73
code/ratl/array_vs.h
Normal file
73
code/ratl/array_vs.h
Normal file
@@ -0,0 +1,73 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Array
|
||||
// -----
|
||||
// This array class is little more than an assert loaded wrapper around a standard
|
||||
// array.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_ARRAY_VS)
|
||||
#define RATL_ARRAY_VS
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class array_vs : public array_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
array_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class array_os : public array_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
array_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class array_is : public array_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
array_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
218
code/ratl/bits_vs.h
Normal file
218
code/ratl/bits_vs.h
Normal file
@@ -0,0 +1,218 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Bit Field
|
||||
// ---------
|
||||
// The bits class is a bit field of any length which supports all the
|
||||
// standard bitwize operations in addition to some operators for adding & removing
|
||||
// individual bits by their integer indicies and a string conversion method.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
// - The SIZE template variable determines how many BITS are available in this template,
|
||||
// not how much memory (number of ints) were used to store it.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_BITS_INC)
|
||||
#define RATL_BITS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Bit Field Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <int SZ>
|
||||
class bits_vs : public bits_base<SZ>
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Call This Function To Set All Bits Beyond SIZE to Zero
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear_trailing_bits()
|
||||
{
|
||||
for (int i=SIZE; i<ARRAY_SIZE*BITS_INT_SIZE; i++)
|
||||
{
|
||||
mV[i>>BITS_SHIFT] &= ~(1<<(i&BITS_AND));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
SIZE = SZ,
|
||||
CAPACITY = SZ,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Standard Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bits_vs(bool init=true,bool initValue=false) : bits_base<SZ>(init,initValue)
|
||||
{
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bits_vs(const bits_vs &B)
|
||||
{
|
||||
mem::cpy(mV, B.mV,BYTE_SIZE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// String Constructor (Format: "100010100101")
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bits_vs(const char* Str)
|
||||
{
|
||||
clear();
|
||||
|
||||
for (int b=0; b<SIZE; b++)
|
||||
{
|
||||
if (!Str[b])
|
||||
{
|
||||
return; // Reached The End Of The String
|
||||
}
|
||||
if (Str[b]=='1')
|
||||
{
|
||||
set_bit(b); // Found A True Bit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Checks If There Are Any Values At All In This Bit Field (Same as operator !())
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
for (int i=0; i<ARRAY_SIZE; i++)
|
||||
{
|
||||
if (mV[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Number Of Bits Represented Here
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Execute A Bitwise Flip On All The Bits
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void invert()
|
||||
{
|
||||
for (int i=0; i<ARRAY_SIZE; i++)
|
||||
{
|
||||
mV[i] = ~mV[i];
|
||||
}
|
||||
clear_trailing_bits();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Execute A Bitwise Flip On All The Bits
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator~()
|
||||
{
|
||||
invert();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Query
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool get_bit(const int i) const
|
||||
{
|
||||
// If you hit this assert, then you are trying
|
||||
// to query a bit that goes beyond the number
|
||||
// of bits this object can hold.
|
||||
//--------------------------------------------
|
||||
assert(i>=0 && i < SIZE);
|
||||
return ( (mV[i>>BITS_SHIFT] & (1<<(i&BITS_AND)))!=0 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Checks If There Are Any Values At All In This Bit Field
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator!() const
|
||||
{
|
||||
return empty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Equality Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator==(const bits_vs &B) const
|
||||
{
|
||||
return (mem::eql(mV, B.mV,BYTE_SIZE));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InEquality Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator!=(const bits_vs &B) const
|
||||
{
|
||||
return !(operator==(B));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Or In From Another Bits Object
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator|=(const bits_vs &B)
|
||||
{
|
||||
for (int i=0; i<ARRAY_SIZE; i++)
|
||||
{
|
||||
mV[i] |= B.mV[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// And In From Another Bits Object
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator&=(const bits_vs &B)
|
||||
{
|
||||
for (int i=0; i<ARRAY_SIZE; i++)
|
||||
{
|
||||
mV[i] &= B.mV[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// xor In From Another Bits Object
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator^=(const bits_vs &B)
|
||||
{
|
||||
for (int i=0; i<ARRAY_SIZE; i++)
|
||||
{
|
||||
mV[i] ^= B.mV[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Assignment Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator=(const bits_vs &B)
|
||||
{
|
||||
mem::cpy(mV, B.mV,BYTE_SIZE);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
526
code/ratl/grid_vs.h
Normal file
526
code/ratl/grid_vs.h
Normal file
@@ -0,0 +1,526 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Grid
|
||||
// ----
|
||||
// There are two versions of the Grid class. Simply, they apply a discreet function
|
||||
// mapping from a n dimensional space to a linear aray.
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_GRID_VS_INC)
|
||||
#define RATL_GRID_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
#if !defined(RATL_ARRAY_VS)
|
||||
#include "array_vs.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The 2D Grid Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <class T, int XSIZE_MAX, int YSIZE_MAX>
|
||||
class grid2_vs : public ratl_base
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
grid2_vs()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
RANGE_NULL = 12345,
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Assignment Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
grid2_vs& operator=(const grid2_vs& other)
|
||||
{
|
||||
mData = other.mData;
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
mSize[i] = other.mSize[i];
|
||||
mMins[i] = other.mMins[i];
|
||||
mMaxs[i] = other.mMaxs[i];
|
||||
mScale[i] = other.mScale[i];
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
void set_size(int xSize, int ySize)
|
||||
{
|
||||
if (xSize<XSIZE_MAX)
|
||||
{
|
||||
mSize[0] = xSize;
|
||||
}
|
||||
if (ySize<YSIZE_MAX)
|
||||
{
|
||||
mSize[1] = ySize;
|
||||
}
|
||||
}
|
||||
|
||||
void snap_scale()
|
||||
{
|
||||
mScale[0] = (float)((int)(mScale[0]));
|
||||
mScale[1] = (float)((int)(mScale[1]));
|
||||
}
|
||||
|
||||
void get_size(int& xSize, int& ySize)
|
||||
{
|
||||
xSize = mSize[0];
|
||||
ySize = mSize[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mSize[0] = XSIZE_MAX;
|
||||
mSize[1] = YSIZE_MAX;
|
||||
mData.clear();
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
mMins[i] = RANGE_NULL;
|
||||
mMaxs[i] = RANGE_NULL;
|
||||
mScale[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Initialize The Entire Grid To A Value
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void init(const T& val)
|
||||
{
|
||||
for (int i=0; i<(XSIZE_MAX*YSIZE_MAX); i++)
|
||||
{
|
||||
mData[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy The Bounds Of Another Grid
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void copy_bounds(const grid2_vs& other)
|
||||
{
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
mSize[i] = other.mSize[i];
|
||||
mMins[i] = other.mMins[i];
|
||||
mMaxs[i] = other.mMaxs[i];
|
||||
mScale[i] = other.mScale[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& get(const int x, const int y)
|
||||
{
|
||||
assert(x>=0 && y>=0 && x<mSize[0] && y<mSize[1]);
|
||||
return mData[(x + y*XSIZE_MAX)];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& get(float x, float y)
|
||||
{
|
||||
assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
truncate_position_to_bounds(x, y);
|
||||
|
||||
int xint = (int)( (x-mMins[0]) / mScale[0] );
|
||||
int yint = (int)( (y-mMins[1]) / mScale[1] );
|
||||
|
||||
assert(xint>=0 && yint>=0 && xint<mSize[0] && yint<mSize[1]);
|
||||
return mData[(xint + yint*XSIZE_MAX)];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert The Scaled Coordinates To A Grid Coordinate
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void get_cell_coords(float x, float y, int& xint, int& yint)
|
||||
{
|
||||
assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
truncate_position_to_bounds(x, y);
|
||||
|
||||
xint = (int)( (x-mMins[0]) / mScale[0] );
|
||||
yint = (int)( (y-mMins[1]) / mScale[1] );
|
||||
|
||||
assert(xint>=0 && yint>=0 && xint<mSize[0] && yint<mSize[1]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expand
|
||||
//
|
||||
// NOTE: This MUST be at least a 2 dimensional point
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void expand_bounds(float xReal, float yReal)
|
||||
{
|
||||
float point[2] = {xReal, yReal};
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
if (point[i]<mMins[i] || mMins[i]==RANGE_NULL)
|
||||
{
|
||||
mMins[i] = point[i];
|
||||
}
|
||||
if (point[i]>mMaxs[i] || mMaxs[i]==RANGE_NULL)
|
||||
{
|
||||
mMaxs[i] = point[i];
|
||||
}
|
||||
}
|
||||
assert(mSize[0]>0 && mSize[1]>0);
|
||||
|
||||
mScale[0] = ((mMaxs[0] - mMins[0])/mSize[0]);
|
||||
mScale[1] = ((mMaxs[1] - mMins[1])/mSize[1]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void truncate_position_to_bounds(float& xReal, float& yReal)
|
||||
{
|
||||
if (xReal<mMins[0])
|
||||
{
|
||||
xReal = mMins[0];
|
||||
}
|
||||
if (xReal>(mMaxs[0]-1.0f))
|
||||
{
|
||||
xReal = mMaxs[0]-1.0f;
|
||||
}
|
||||
if (yReal<mMins[1])
|
||||
{
|
||||
yReal = mMins[1];
|
||||
}
|
||||
if (yReal>(mMaxs[1]-1.0f))
|
||||
{
|
||||
yReal = mMaxs[1]-1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void get_cell_position(int x, int y, float& xReal, float& yReal)
|
||||
{
|
||||
// assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
xReal = (x * mScale[0]) + mMins[0] + (mScale[0] * 0.5f);
|
||||
yReal = (y * mScale[1]) + mMins[1] + (mScale[1] * 0.5f);
|
||||
}
|
||||
void get_cell_upperleft(int x, int y, float& xReal, float& yReal)
|
||||
{
|
||||
// assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
xReal = (x * mScale[0]) + mMins[0];
|
||||
yReal = (y * mScale[1]) + mMins[1];
|
||||
}
|
||||
void get_cell_lowerright(int x, int y, float& xReal, float& yReal)
|
||||
{
|
||||
// assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
xReal = (x * mScale[0]) + mMins[0] + (mScale[0]);
|
||||
yReal = (y * mScale[1]) + mMins[1] + (mScale[1]);
|
||||
}
|
||||
void scale_by_largest_axis(float& dist)
|
||||
{
|
||||
assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
if (mScale[0]>mScale[1])
|
||||
{
|
||||
dist /= mScale[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
dist /= mScale[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
private:
|
||||
array_vs<T, XSIZE_MAX*YSIZE_MAX> mData;
|
||||
|
||||
int mSize[2];
|
||||
float mMins[2];
|
||||
float mMaxs[2];
|
||||
float mScale[2];
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Raw Get - For The Iterator Dereference Function
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& rawGet(int Loc)
|
||||
{
|
||||
assert(Loc>=0 && Loc<XSIZE_MAX*YSIZE_MAX);
|
||||
return mData[Loc];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
//--------------
|
||||
iterator() {}
|
||||
iterator(grid2_vs* p, int t) : mOwner(p), mLoc(t) {}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const iterator &t) {mOwner=t.mOwner; mLoc=t.mLoc;}
|
||||
|
||||
// Equality & Inequality Operators
|
||||
//---------------------------------
|
||||
bool operator!=(const iterator &t) {return (mLoc!=t.mLoc);}
|
||||
bool operator==(const iterator &t) {return (mLoc==t.mLoc);}
|
||||
|
||||
// Dereference Operator
|
||||
//----------------------
|
||||
T& operator* () {return (mOwner->rawGet(mLoc));}
|
||||
|
||||
// Inc Operator
|
||||
//--------------
|
||||
void operator++(int) {mLoc++;}
|
||||
|
||||
|
||||
// Row & Col Offsets
|
||||
//-------------------
|
||||
void offsetRows(int num) {mLoc += (YSIZE_MAX*num);}
|
||||
void offsetCols(int num) {mLoc += (num);}
|
||||
|
||||
|
||||
// Return True If On Frist Column Of A Row
|
||||
//-----------------------------------------
|
||||
bool onColZero()
|
||||
{
|
||||
return (mLoc%XSIZE_MAX)==0;
|
||||
}
|
||||
|
||||
// Evaluate The XY Position Of This Iterator
|
||||
//-------------------------------------------
|
||||
void position(int& X, int& Y)
|
||||
{
|
||||
Y = mLoc / XSIZE_MAX;
|
||||
X = mLoc - (Y*XSIZE_MAX);
|
||||
}
|
||||
|
||||
private:
|
||||
int mLoc;
|
||||
grid2_vs* mOwner;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Begin
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator begin(int x=0, int y=0)
|
||||
{
|
||||
assert(x>=0 && y>=0 && x<mSize[0] && y<mSize[1]);
|
||||
|
||||
return iterator(this, (x + y*XSIZE_MAX));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Begin (scaled position, use mins and maxs to calc real position)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator begin(float xReal, float yReal)
|
||||
{
|
||||
assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
truncate_position_to_bounds(xReal, yReal);
|
||||
|
||||
int x = (int)( (xReal-mMins[0]) / mScale[0] );
|
||||
int y = (int)( (yReal-mMins[1]) / mScale[1] );
|
||||
|
||||
return begin(x,y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator End
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator end()
|
||||
{
|
||||
return iterator(this, (XSIZE_MAX*YSIZE_MAX));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Ranged Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class riterator
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
//--------------
|
||||
riterator()
|
||||
{}
|
||||
riterator(grid2_vs* p, int Range, int SX, int SY) :
|
||||
mOwner(p)
|
||||
{
|
||||
int Start[2] = {SX, SY};
|
||||
int Bounds[2] = {XSIZE_MAX-1, YSIZE_MAX-1};
|
||||
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
mMins[i] = Start[i] - Range;
|
||||
mMaxs[i] = Start[i] + Range;
|
||||
|
||||
if (mMins[i]<0)
|
||||
{
|
||||
mMins[i] = 0;
|
||||
}
|
||||
if (mMaxs[i] > Bounds[i])
|
||||
{
|
||||
mMaxs[i] = Bounds[i];
|
||||
}
|
||||
|
||||
mLoc[i] = mMins[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const riterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
mMins[i] = t.mMins[i];
|
||||
mMaxs[i] = t.mMaxs[i];
|
||||
mLoc[i] = t.mLoc[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Equality & Inequality Operators
|
||||
//---------------------------------
|
||||
bool operator!=(const riterator &t)
|
||||
{
|
||||
return (mLoc[0]!=t.mLoc[0] || mLoc[1]!=t.mLoc[1]);
|
||||
}
|
||||
bool operator==(const riterator &t)
|
||||
{
|
||||
return (mLoc[0]==t.mLoc[0] && mLoc[1]==t.mLoc[1]);
|
||||
}
|
||||
|
||||
// Dereference Operator
|
||||
//----------------------
|
||||
T& operator* ()
|
||||
{
|
||||
return (mOwner->get(mLoc[0], mLoc[1]));
|
||||
}
|
||||
|
||||
// Inc Operator
|
||||
//--------------
|
||||
void operator++(int)
|
||||
{
|
||||
if (mLoc[1] <= mMaxs[1])
|
||||
{
|
||||
mLoc[0]++;
|
||||
if (mLoc[0]>(mMaxs[0]))
|
||||
{
|
||||
mLoc[0] = mMins[0];
|
||||
mLoc[1]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool at_end()
|
||||
{
|
||||
return (mLoc[1]>mMaxs[1]);
|
||||
}
|
||||
|
||||
|
||||
// Return True If On Frist Column Of A Row
|
||||
//-----------------------------------------
|
||||
bool onColZero()
|
||||
{
|
||||
return (mLoc[0]==mMins[0]);
|
||||
}
|
||||
|
||||
// Evaluate The XY Position Of This Iterator
|
||||
//-------------------------------------------
|
||||
void position(int& X, int& Y)
|
||||
{
|
||||
Y = mLoc[1];
|
||||
X = mLoc[0];
|
||||
}
|
||||
|
||||
private:
|
||||
int mMins[2];
|
||||
int mMaxs[2];
|
||||
int mLoc[2];
|
||||
grid2_vs* mOwner;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Ranged Iterator Begin (x and y are the center of the range)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
riterator rangeBegin(int range, int x, int y)
|
||||
{
|
||||
assert(x>=0 && y>=0 && x<XSIZE_MAX && y<YSIZE_MAX);
|
||||
return riterator(this, range, x, y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
riterator rangeBegin(int range, float xReal, float yReal)
|
||||
{
|
||||
float position[2] = {xReal, yReal};
|
||||
assert(mScale[0]!=0.0f && mScale[1]!=0.0f);
|
||||
truncate_position_to_bounds(xReal, yReal);
|
||||
int x = ( (position[0]-mMins[0]) / mScale[0] );
|
||||
int y = ( (position[1]-mMins[1]) / mScale[1] );
|
||||
|
||||
assert(x>=0 && y>=0 && x<XSIZE_MAX && y<YSIZE_MAX);
|
||||
return riterator(this, range, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
291
code/ratl/handle_pool_vs.h
Normal file
291
code/ratl/handle_pool_vs.h
Normal file
@@ -0,0 +1,291 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Handle Pool
|
||||
// -----------
|
||||
// The memory pool class is a simple routine for constant time allocation and deallocation
|
||||
// from a fixed size pool of objects. The class uses a simple array to hold the actual
|
||||
// data, a queue for the free list, and a bit field to mark which spots in the array
|
||||
// are allocated.
|
||||
//
|
||||
// In addition to the standard memory pool features, this Handle Pool provides a fast
|
||||
// iterator, asserts on attempting to access unused data, and a unique ID "handle" for
|
||||
// the external system to use.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_HANDLE_POOL_VS_INC)
|
||||
#define RATL_HANDLE_POOL_VS_INC
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
#if !defined(RATL_POOL_VS_INC)
|
||||
#include "pool_vs.h"
|
||||
#endif
|
||||
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
template <class T>
|
||||
class handle_pool_base : public pool_root<T>
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
|
||||
private:
|
||||
int mHandles[CAPACITY];
|
||||
int mMASK_HANDLE_TO_INDEX;
|
||||
int mMASK_NUM_BITS;
|
||||
|
||||
void IncHandle(int index)
|
||||
{
|
||||
mHandles[index] += (1<<mMASK_NUM_BITS);
|
||||
if (mHandles[index]<0)
|
||||
{
|
||||
// we rolled over
|
||||
mHandles[index] = index; // Reset The ID Counter
|
||||
mHandles[index] |= (1<<mMASK_NUM_BITS);
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
//
|
||||
// We need a routine to calculate the MASK used to convert a handle to an index and
|
||||
// the number of bits needed to shift by.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
handle_pool_base()
|
||||
{
|
||||
mMASK_HANDLE_TO_INDEX = 0;
|
||||
mMASK_NUM_BITS = 0;
|
||||
|
||||
int value=CAPACITY-1;
|
||||
while(value)
|
||||
{
|
||||
value>>= 1;
|
||||
|
||||
mMASK_HANDLE_TO_INDEX <<= 1;
|
||||
mMASK_HANDLE_TO_INDEX |= 1;
|
||||
mMASK_NUM_BITS++;
|
||||
}
|
||||
for (int i=0; i<CAPACITY; i++)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
mHandles[i] = i; // Reset The ID Counter
|
||||
mHandles[i] |= ((++HandleSaltValue)<<mMASK_NUM_BITS);
|
||||
#else
|
||||
mHandles[i] = i; // Reset The ID Counter
|
||||
mHandles[i] |= (1<<mMASK_NUM_BITS);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear - Removes all allocation information
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
pool_root<T>::clear();
|
||||
// note that we do not refill the handles cause we want old handles to still be stale
|
||||
for (int i=0; i<CAPACITY; i++)
|
||||
{
|
||||
IncHandle(i);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constant Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue& operator[](int handle) const
|
||||
{
|
||||
assert(is_used(handle)); //typically this is a stale handle (already been freed)
|
||||
return value_at_index(handle&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue& operator[](int i)
|
||||
{
|
||||
assert(is_used(i)); //typically this is a stale handle (already been freed)
|
||||
return value_at_index(i&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
|
||||
bool is_used(int i) const
|
||||
{
|
||||
if (mHandles[i&mMASK_HANDLE_TO_INDEX]==i)
|
||||
{
|
||||
return is_used_index(i&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swap two items based on handle
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void swap(int i,int j)
|
||||
{
|
||||
assert(is_used(i)); //typically this is a stale handle (already been freed)
|
||||
assert(is_used(j)); //typically this is a stale handle (already been freed)
|
||||
swap_index(handle_to_index(i),handle_to_index(j));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator returns a handle
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int alloc()
|
||||
{
|
||||
int index=alloc_index();
|
||||
return mHandles[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator, with value, returns a handle
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int alloc(const TTValue &v)
|
||||
{
|
||||
int index=alloc_index(v);
|
||||
return mHandles[index];
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Deallocator, by index, not something generally needed
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void free_index(int index)
|
||||
{
|
||||
pool_root<T>::free_index(index);
|
||||
IncHandle(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Deallocator, by handle
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void free(int handle)
|
||||
{
|
||||
assert(is_used(handle));
|
||||
free_index(handle&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Deallocator, by pointer
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void free(TTValue *me)
|
||||
{
|
||||
free_index(pointer_to_index(me));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a handle to a raw index, not generally something you should use
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int handle_to_index(int handle) const
|
||||
{
|
||||
assert(is_used(handle));
|
||||
return (handle&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// FInd the handle for a given index, this cannot check for stale handles, so it is ill advised
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int index_to_handle(int index) const
|
||||
{
|
||||
assert(index>=0 && index<CAPACITY && is_used_index(index)); //disallowing this on stale handles
|
||||
return (mHandles[index]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// converts a T pointer to a handle, generally not something you need, cannot check for stale handles
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int pointer_to_handle(const TTValue *me) const
|
||||
{
|
||||
return index_to_handle(pointer_to_index(me));
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// converts a T pointer to a handle, generally not something you need, cannot check for stale handles
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int pointer_to_handle(const TRatlNew *me) const
|
||||
{
|
||||
return index_to_handle(pointer_to_index(me));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The Object At handle
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
pool_root<T>::iterator at(int handle)
|
||||
{
|
||||
assert(is_used(handle));
|
||||
return at_index(handle&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The Object At handle
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
pool_root<T>::const_iterator at(int handle) const
|
||||
{
|
||||
assert(is_used(handle));
|
||||
return at_index(handle&mMASK_HANDLE_TO_INDEX);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class handle_pool_vs : public handle_pool_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
handle_pool_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class handle_pool_os : public handle_pool_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
handle_pool_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class handle_pool_is : public handle_pool_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
handle_pool_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
200
code/ratl/hash_pool_vs.h
Normal file
200
code/ratl/hash_pool_vs.h
Normal file
@@ -0,0 +1,200 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Hash Pool
|
||||
// ---------
|
||||
// The hash pool stores raw data of variable size. It uses a hash table to check for
|
||||
// redundant data, and upon finding any, will return the existing handle. Otherwise
|
||||
// it copies the data to memory and returns a new handle.
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_HASH_POOL_VS_INC)
|
||||
#define RATL_HASH_POOL_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Hash Pool
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <int SIZE, int SIZE_HANDLES>
|
||||
class hash_pool
|
||||
{
|
||||
int mHandles[SIZE_HANDLES]; // each handle holds the start index of it's data
|
||||
|
||||
int mDataAlloc; // where the next chunck of data will go
|
||||
char mData[SIZE];
|
||||
|
||||
#ifdef _DEBUG
|
||||
int mFinds; // counts how many total finds have run
|
||||
int mCurrentCollisions; // counts how many collisions on the last find
|
||||
int mTotalCollisions; // counts the total number of collisions
|
||||
int mTotalAllocs;
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// This function searches for a handle which already stores the data (assuming the
|
||||
// handle is a hash within range SIZE_HANDLES).
|
||||
//
|
||||
// If it failes, it returns false, and the handle passed in points to the next
|
||||
// free slot.
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool find_existing(int& handle, const void* data, int datasize)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
mFinds++;
|
||||
mCurrentCollisions = 0;
|
||||
#endif
|
||||
|
||||
while (mHandles[handle]) // So long as a handle exists there
|
||||
{
|
||||
if (mem::eql((void*)(&mData[mHandles[handle]]), data, datasize))
|
||||
{
|
||||
return true; // found
|
||||
}
|
||||
handle=(handle+1)&(SIZE_HANDLES-1); // incriment the handle
|
||||
|
||||
#ifdef _DEBUG
|
||||
mCurrentCollisions ++;
|
||||
mTotalCollisions ++;
|
||||
|
||||
//assert(mCurrentCollisions < 16); // If We Had 16+ Collisions, Hash May Be Inefficient.
|
||||
// Evaluate SIZE and SIZEHANDLES
|
||||
#endif
|
||||
}
|
||||
return false; // failed to find
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// A simple hash function for the range of [0, SIZE_HANDLES]
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int hash(const void* data, int datasize)
|
||||
{
|
||||
int h=0;
|
||||
for (int i=0; i<datasize; i++)
|
||||
{
|
||||
h += ((const char*)(data))[i] * (i + 119); // 119. Prime Number?
|
||||
}
|
||||
h &= SIZE_HANDLES - 1; // zero out bits beyoned SIZE_HANDLES
|
||||
return h;
|
||||
}
|
||||
|
||||
public:
|
||||
hash_pool()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Number Of Bytes Allocated
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return mDataAlloc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If This Memory Pool Is Empty
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
return (mDataAlloc==1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If This Memory Pool Has Enough Space Left For (minimum) Bytes
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full(int minimum) const
|
||||
{
|
||||
return ((SIZE - mDataAlloc)<minimum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear - Removes all allocation information - Note! DOES NOT CLEAR MEMORY
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mData[0] = 0;
|
||||
mDataAlloc = 1;
|
||||
for (int i=0; i<SIZE_HANDLES; i++)
|
||||
{
|
||||
mHandles[i] = 0;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
mFinds = 0;
|
||||
mCurrentCollisions = 0;
|
||||
mTotalCollisions = 0;
|
||||
mTotalAllocs = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// This is the primary functionality of the hash pool. It will search for existing
|
||||
// data of the same size, and failing to find any, it will append the data to the
|
||||
// memory.
|
||||
//
|
||||
// In both cases, it gives you a handle to look up the data later.
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int get_handle(const void* data, int datasize)
|
||||
{
|
||||
int handle = hash(data, datasize); // Initialize Our Handle By Hash Fcn
|
||||
if (!find_existing(handle, data, datasize))
|
||||
{
|
||||
assert(mDataAlloc+datasize < SIZE); // Is There Enough Memory?
|
||||
|
||||
#ifdef _DEBUG
|
||||
mTotalAllocs++;
|
||||
#endif
|
||||
|
||||
mem::cpy((void*)(&mData[mDataAlloc]), data, datasize);// Copy Data To Memory
|
||||
mHandles[handle] = mDataAlloc; // Mark Memory In Hash Tbl
|
||||
mDataAlloc += datasize; // Adjust Next Alloc Location
|
||||
}
|
||||
return handle; // Return The Hash Tbl handleess
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constant Access Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const void* operator[](int handle) const
|
||||
{
|
||||
assert(handle>=0 && handle<SIZE_HANDLES);
|
||||
|
||||
return &(mData[mHandles[handle]]);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
float average_collisions() {return ((float)mTotalCollisions / (float)mFinds);}
|
||||
int total_allocs() {return mTotalAllocs;}
|
||||
int total_finds() {return mFinds;}
|
||||
int total_collisions() {return mTotalCollisions;}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
324
code/ratl/heap_vs.h
Normal file
324
code/ratl/heap_vs.h
Normal file
@@ -0,0 +1,324 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Heap
|
||||
// ------
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// TODO:
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_HEAP_VS_INC)
|
||||
#define RATL_HEAP_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Vector Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
class heap_base : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
private:
|
||||
array_base<TStorageTraits> mData; // The Memory
|
||||
int mPush; // Address Of Next Add Location
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns The Location Of Node (i)'s Parent Node (The Parent Node Of Zero Is Zero)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
static int parent(int i)
|
||||
{
|
||||
return ((i-1)/2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns The Location Of Node (i)'s Left Child (The Child Of A Leaf Is The Leaf)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
static int left(int i)
|
||||
{
|
||||
return (2*i)+1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns The Location Of Node (i)'s Right Child (The Child Of A Leaf Is The Leaf)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
static int right(int i)
|
||||
{
|
||||
return (2*i)+2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns The Location Of Largest Child Of Node (i)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int largest_child(int i) const
|
||||
{
|
||||
if (left(i)<mPush)
|
||||
{
|
||||
if (right(i)<mPush)
|
||||
{
|
||||
return ( (mData[right(i)] < mData[left(i)]) ? (left(i)) : (right(i)) );
|
||||
}
|
||||
return left(i); // Node i only has a left child, so by default it is the biggest
|
||||
}
|
||||
return i; // Node i is a leaf, so just return it
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swaps Two Element Locations
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void swap(int a, int b)
|
||||
{
|
||||
if (a==b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(a>=0 && b>=0 && a<CAPACITY && b<CAPACITY);
|
||||
mData.swap(a,b);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swaps The Data Up The Heap Until It Reaches A Valid Location
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void reheapify_upward(int Pos)
|
||||
{
|
||||
while (Pos && mData[parent(Pos)]<mData[Pos])
|
||||
{
|
||||
swap(parent(Pos), Pos);
|
||||
Pos = parent(Pos);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swaps The Data Down The Heap Until It Reaches A Valid Location
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void reheapify_downward(int Pos)
|
||||
{
|
||||
int largestChild = largest_child(Pos);
|
||||
while (largestChild!=Pos && mData[Pos]<mData[largestChild])
|
||||
{
|
||||
swap(largestChild, Pos);
|
||||
Pos = largestChild;
|
||||
largestChild = largest_child(Pos);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Validate Will Run Through The Heap And Make Sure The Top Element Is Smallest
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool valid()
|
||||
{
|
||||
for (int i=1; i<mPush; i++)
|
||||
{
|
||||
if (mData[0]<mData[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
heap_base() : mPush(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Size (The Difference Between The Push And Pop "Pointers")
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return mPush;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If The Size Is Zero
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
return !size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If The Size Is Full
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
return size()==CAPACITY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Empty Out The Entire Heap
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mPush = 0;
|
||||
mData.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Data Value At The Top Of The Heap
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue & top() const
|
||||
{
|
||||
assert(mPush>0); // Don't Try To Look At This If There Is Nothing In Here
|
||||
return mData[0];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value To The Queue
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push(const TTValue& nValue)
|
||||
{
|
||||
assert(size()<CAPACITY);
|
||||
|
||||
// Add It
|
||||
//--------
|
||||
mData.construct(mPush,nValue);
|
||||
|
||||
// Fix Possible Heap Inconsistancies
|
||||
//-----------------------------------
|
||||
reheapify_upward(mPush);
|
||||
|
||||
mPush++;
|
||||
assert(valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Alloc A Value, call push_alloced to add
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue& alloc()
|
||||
{
|
||||
assert(size()<CAPACITY);
|
||||
|
||||
// Add It
|
||||
//--------
|
||||
mData.construct(mPush);
|
||||
|
||||
return mData[mPush];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Alloc A Raw Value for placement new, call push_alloced to add
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew * alloc_raw()
|
||||
{
|
||||
assert(size()<CAPACITY);
|
||||
|
||||
return mData.alloc_raw(mPush);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value To The Queue, after filling an alloced slot
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push_alloced()
|
||||
{
|
||||
assert(size()<CAPACITY);
|
||||
// Fix Possible Heap Inconsistancies
|
||||
//-----------------------------------
|
||||
reheapify_upward(mPush);
|
||||
|
||||
mPush++;
|
||||
assert(valid());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove A Value From The Queue
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void pop()
|
||||
{
|
||||
assert(size()>0);
|
||||
|
||||
mPush--;
|
||||
|
||||
// Swap The Lowest Element Up To The Spot We Just "Erased"
|
||||
//---------------------------------------------------------
|
||||
swap(0, mPush);
|
||||
mData.destruct(mPush);
|
||||
|
||||
// Fix Possible Heap Inconsistancies
|
||||
//-----------------------------------
|
||||
reheapify_downward(0);
|
||||
assert(valid());
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class heap_vs : public heap_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
heap_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class heap_os : public heap_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
heap_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class heap_is : public heap_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
heap_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
751
code/ratl/list_vs.h
Normal file
751
code/ratl/list_vs.h
Normal file
@@ -0,0 +1,751 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// List
|
||||
// ----
|
||||
// The list class supports ordered insertion and deletion in O(1) constant time.
|
||||
// It simulates a linked list of pointers by allocating free spots in a pool and
|
||||
// maintaining "links" as indicies to the pool array objects.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_LIST_VS_INC)
|
||||
#define RATL_LIST_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(RA_DEBUG_LINKING)
|
||||
#pragma message("...including list_vs.h")
|
||||
#endif
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
#if !defined(RATL_POOL_VS_INC)
|
||||
#include "pool_vs.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
// this is private to the list, but you have no access to it, soooo..
|
||||
class list_node
|
||||
{
|
||||
public:
|
||||
int mNext;
|
||||
int mPrev;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The List Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <class T>
|
||||
class list_base : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
pool_base<TStorageTraits> mPool; // The Allocation Data Pool
|
||||
|
||||
int mFront; // The Beginning Of The List
|
||||
int mBack; // The End Of The List
|
||||
enum
|
||||
{
|
||||
NULL_NODE = -1
|
||||
};
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
list_base() : mFront(NULL_NODE), mBack(NULL_NODE)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// How Many Objects Are In This List
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return (mPool.size());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Are There Any Objects In This List?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
assert(mFront!=NULL_NODE || size()==0);
|
||||
return (mFront==NULL_NODE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Is This List Filled?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
return (mPool.full());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear All Elements
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mFront = NULL_NODE;
|
||||
mBack = NULL_NODE;
|
||||
mPool.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The First Object In The List
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue & front()
|
||||
{
|
||||
assert(mFront!=NULL_NODE); // this is empty
|
||||
return mPool[mFront];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Last Object In The List
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue & back()
|
||||
{
|
||||
assert(mBack!=NULL_NODE);
|
||||
return mPool[mBack];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The First Object In The List
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue & front() const
|
||||
{
|
||||
assert(mFront!=NULL_NODE); // this is empty
|
||||
return mPool[mFront];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Last Object In The List
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue & back() const
|
||||
{
|
||||
assert(mBack!=NULL_NODE);
|
||||
return mPool[mBack];
|
||||
}
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class const_iterator;
|
||||
class iterator
|
||||
{
|
||||
friend class list_base<T>;
|
||||
friend class const_iterator;
|
||||
|
||||
int mLoc;
|
||||
list_base<T>* mOwner;
|
||||
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
iterator() : mOwner(0), mLoc(0)
|
||||
{}
|
||||
iterator(list_base* p, int t) : mOwner(p), mLoc(t)
|
||||
{}
|
||||
iterator(const iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc)
|
||||
{}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mLoc = t.mLoc;
|
||||
}
|
||||
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const iterator &t) const
|
||||
{
|
||||
return (mLoc!=t.mLoc || mOwner!=t.mOwner);
|
||||
}
|
||||
bool operator==(const iterator &t) const
|
||||
{
|
||||
return (mLoc==t.mLoc && mOwner==t.mOwner);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
TTValue& operator* () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
return (mOwner->mPool[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
TTValue& value() const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
return (mOwner->mPool[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
TTValue* operator-> () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
return (&mOwner->mPool[mLoc]);
|
||||
}
|
||||
|
||||
// prefix Inc Operator
|
||||
//--------------
|
||||
iterator operator++(int)
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
iterator old(*this);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mNext;
|
||||
return old;
|
||||
}
|
||||
|
||||
// postfix Inc Operator
|
||||
//--------------
|
||||
iterator operator++()
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mNext;
|
||||
return *this;
|
||||
}
|
||||
// prefix Inc Operator
|
||||
//--------------
|
||||
iterator operator--(int)
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
iterator old(*this);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mPrev;
|
||||
return old;
|
||||
}
|
||||
|
||||
//--------------
|
||||
// postfix Dec Operator
|
||||
//--------------
|
||||
iterator operator--()
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mPrev;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constant Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class const_iterator
|
||||
{
|
||||
friend class list_base<T>;
|
||||
|
||||
int mLoc;
|
||||
const list_base<T>* mOwner;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
const_iterator() : mOwner(0), mLoc(0)
|
||||
{}
|
||||
const_iterator(const list_base* p, int t) : mOwner(p), mLoc(t)
|
||||
{}
|
||||
const_iterator(const const_iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc)
|
||||
{}
|
||||
const_iterator(const iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc)
|
||||
{}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const const_iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mLoc = t.mLoc;
|
||||
}
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mLoc = t.mLoc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const iterator &t) const
|
||||
{
|
||||
return (mLoc!=t.mLoc || mOwner!=t.mOwner);
|
||||
}
|
||||
bool operator==(const iterator &t) const
|
||||
{
|
||||
return (mLoc==t.mLoc && mOwner==t.mOwner);
|
||||
}
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const const_iterator &t) const
|
||||
{
|
||||
return (mLoc!=t.mLoc || mOwner!=t.mOwner);
|
||||
}
|
||||
bool operator==(const const_iterator &t) const
|
||||
{
|
||||
return (mLoc==t.mLoc && mOwner==t.mOwner);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const TTValue& operator* () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
return (mOwner->mPool[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const TTValue* operator-> () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
return (&mOwner->mPool[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const TTValue& value() const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
return (mOwner->mPool[mLoc]);
|
||||
}
|
||||
|
||||
// prefix Inc Operator
|
||||
//--------------
|
||||
const_iterator operator++(int)
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
const_iterator old(*this);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mNext;
|
||||
return old;
|
||||
}
|
||||
|
||||
// postfix Inc Operator
|
||||
//--------------
|
||||
const_iterator operator++()
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mNext;
|
||||
return *this;
|
||||
}
|
||||
// prefix Inc Operator
|
||||
//--------------
|
||||
const_iterator operator--(int)
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
const_iterator old(*this);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mPrev;
|
||||
return old;
|
||||
}
|
||||
|
||||
//--------------
|
||||
// postfix Dec Operator
|
||||
//--------------
|
||||
const_iterator operator--()
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<T::CAPACITY);
|
||||
mLoc = T::node(mOwner->mPool[mLoc]).mPrev;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Begin (Starts At Address mFront)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(this, mFront);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Begin (Starts At Address mFront)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(this, mFront);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Reverse Iterator Begin (Starts At Address mBack)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator rbegin()
|
||||
{
|
||||
return iterator(this, mBack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Reverse Iterator Begin (Starts At Address mBack)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator rbegin() const
|
||||
{
|
||||
return const_iterator(this, mBack);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator End (Set To Address NULL_NODE) Should Work For Forward & Backward Iteration
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator end()
|
||||
{
|
||||
return iterator(this, NULL_NODE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator End (Set To Address NULL_NODE) Should Work For Forward & Backward Iteration
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(this, NULL_NODE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert (BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& insert(const iterator& it)
|
||||
{
|
||||
int nNew= mPool.alloc();
|
||||
insert_low(it,nNew);
|
||||
return mPool[mNew];
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert Value(BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void insert(const iterator& it, const TTValue& val)
|
||||
{
|
||||
int nNew= mPool.alloc(val);
|
||||
insert_low(it,nNew);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert Raw(BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew* insert_raw(const iterator& it)
|
||||
{
|
||||
TRatlNew *ret = mPool.alloc_raw();
|
||||
insert_low(it,mPool.pointer_to_index(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert (AFTER POINTED ELEMENT) (ALSO - NOT CONSTANT, WILL CHANGE it)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& insert_after(iterator& it)
|
||||
{
|
||||
int nNew= mPool.alloc();
|
||||
insert_low_after(it,nNew);
|
||||
it = iterator(this, nNew);
|
||||
return mPool[mNew];
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert Value(AFTER POINTED ELEMENT) (ALSO - NOT CONSTANT, WILL CHANGE it)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void insert_after(iterator& it, const TTValue& val)
|
||||
{
|
||||
int nNew= mPool.alloc(val);
|
||||
insert_low_after(it,nNew);
|
||||
it = iterator(this, nNew);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert Raw(AFTER POINTED ELEMENT) (ALSO - NOT CONSTANT, WILL CHANGE it)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew* insert_raw_after(iterator& it)
|
||||
{
|
||||
TRatlNew *ret = mPool.alloc_raw();
|
||||
insert_low_after(it,mPool.pointer_to_index(ret));
|
||||
it = iterator(this, mPool.pointer_to_index(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Front Insert (BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& push_front()
|
||||
{
|
||||
int nNew= mPool.alloc();
|
||||
insert_low(begin(),nNew);
|
||||
return mPool[mNew];
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Front Insert Value(BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push_front(const TTValue& val)
|
||||
{
|
||||
int nNew= mPool.alloc(val);
|
||||
insert_low(begin(),nNew);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Front Insert Raw(BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew * push_front_raw()
|
||||
{
|
||||
TRatlNew *ret = mPool.alloc_raw();
|
||||
insert_low(begin(),mPool.pointer_to_index(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Front Insert (BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
T& push_back()
|
||||
{
|
||||
int nNew= mPool.alloc();
|
||||
insert_low(end(),nNew);
|
||||
return mPool[mNew];
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Front Insert Value(BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push_back(const TTValue& val)
|
||||
{
|
||||
int nNew= mPool.alloc(val);
|
||||
insert_low(end(),nNew);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Front Insert Raw(BEFORE POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew * push_back_raw()
|
||||
{
|
||||
TRatlNew *ret = mPool.alloc_raw();
|
||||
insert_low(end(),mPool.pointer_to_index(ret));
|
||||
return ret;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Erase
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void erase(iterator& it)
|
||||
{
|
||||
assert(it.mOwner==this); // Iterators must be mixed up, this is from a different list.
|
||||
assert(it.mLoc!=NULL_NODE);
|
||||
|
||||
int At = it.mLoc;
|
||||
int Prev = T::node(mPool[At]).mPrev;
|
||||
int Next = T::node(mPool[At]).mNext;
|
||||
|
||||
// LINK: (Prev)<-(At)--(Next)
|
||||
//--------------------------------------------
|
||||
if (Next!=NULL_NODE)
|
||||
{
|
||||
T::node(mPool[Next]).mPrev = Prev;
|
||||
}
|
||||
|
||||
// LINK: (Prev)--(At)->(Next)
|
||||
//--------------------------------------------
|
||||
if (Prev!=NULL_NODE)
|
||||
{
|
||||
T::node(mPool[Prev]).mNext = Next;
|
||||
}
|
||||
|
||||
// UPDATE: Front & Back
|
||||
//----------------------
|
||||
if (At==mBack)
|
||||
{
|
||||
mBack = Prev;
|
||||
}
|
||||
if (At==mFront)
|
||||
{
|
||||
mFront = Next;
|
||||
}
|
||||
|
||||
// ERASE At
|
||||
//--------------------------------------------
|
||||
mPool.free(At);
|
||||
it.mLoc = Prev;
|
||||
}
|
||||
template<class CAST_TO>
|
||||
CAST_TO *verify_alloc(CAST_TO *p) const
|
||||
{
|
||||
return mPool.verify_alloc(p);
|
||||
}
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert, returns pool index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void insert_low(const iterator& it,int nNew)
|
||||
{
|
||||
assert(it.mOwner==this); // Iterators must be mixed up, this is from a different list.
|
||||
|
||||
int Next = it.mLoc;
|
||||
int Prev = NULL_NODE;
|
||||
if (Next!=NULL_NODE)
|
||||
{
|
||||
Prev = T::node(mPool[Next]).mPrev;
|
||||
}
|
||||
else
|
||||
{
|
||||
Prev = mBack;
|
||||
}
|
||||
|
||||
|
||||
assert(nNew!=Next && nNew!=Prev);
|
||||
|
||||
|
||||
// LINK: (Prev)<-(New)->(Next)
|
||||
//--------------------------------------------
|
||||
T::node(mPool[nNew]).mPrev = Prev;
|
||||
T::node(mPool[nNew]).mNext = Next;
|
||||
|
||||
|
||||
// LINK: (New)<-(Next)
|
||||
//--------------------------------------------
|
||||
if (Next!=NULL_NODE)
|
||||
{
|
||||
T::node(mPool[Next]).mPrev = nNew;
|
||||
assert(T::node(mPool[Next]).mPrev!=T::node(mPool[Next]).mNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBack = nNew;
|
||||
}
|
||||
|
||||
|
||||
// LINK: (Prev)->(New)
|
||||
//--------------------------------------------
|
||||
if (Prev!=NULL_NODE)
|
||||
{
|
||||
T::node(mPool[Prev]).mNext = nNew;
|
||||
assert(T::node(mPool[Prev]).mPrev!=T::node(mPool[Prev]).mNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFront = nNew;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Insert, returns pool index (AFTER POINTED ELEMENT)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void insert_low_after(const iterator& it,int nNew)
|
||||
{
|
||||
assert(it.mOwner==this); // Iterators must be mixed up, this is from a different list.
|
||||
|
||||
int Next = NULL_NODE;//it.mLoc;
|
||||
int Prev = it.mLoc;//NULL_NODE;
|
||||
if (Prev!=NULL_NODE)
|
||||
{
|
||||
Next = T::node(mPool[Prev]).mNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
Prev = mFront;
|
||||
}
|
||||
|
||||
|
||||
assert(nNew!=Next && nNew!=Prev);
|
||||
|
||||
|
||||
// LINK: (Prev)<-(New)->(Next)
|
||||
//--------------------------------------------
|
||||
T::node(mPool[nNew]).mPrev = Prev;
|
||||
T::node(mPool[nNew]).mNext = Next;
|
||||
|
||||
|
||||
// LINK: (New)<-(Next)
|
||||
//--------------------------------------------
|
||||
if (Next!=NULL_NODE)
|
||||
{
|
||||
T::node(mPool[Next]).mPrev = nNew;
|
||||
assert(T::node(mPool[Next]).mPrev!=T::node(mPool[Next]).mNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBack = nNew;
|
||||
}
|
||||
|
||||
|
||||
// LINK: (Prev)->(New)
|
||||
//--------------------------------------------
|
||||
if (Prev!=NULL_NODE)
|
||||
{
|
||||
T::node(mPool[Prev]).mNext = nNew;
|
||||
assert(T::node(mPool[Prev]).mPrev!=T::node(mPool[Prev]).mNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFront = nNew;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class list_vs : public list_base<storage::value_semantics_node<T,ARG_CAPACITY,list_node> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics_node<T,ARG_CAPACITY,list_node> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
list_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class list_os : public list_base<storage::object_semantics_node<T,ARG_CAPACITY,list_node> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics_node<T,ARG_CAPACITY,list_node> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
list_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class list_is : public list_base<storage::virtual_semantics_node<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE,list_node> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics_node<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE,list_node> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
list_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
1629
code/ratl/map_vs.h
Normal file
1629
code/ratl/map_vs.h
Normal file
File diff suppressed because it is too large
Load Diff
570
code/ratl/pool_vs.h
Normal file
570
code/ratl/pool_vs.h
Normal file
@@ -0,0 +1,570 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Memory Pool
|
||||
// -----------
|
||||
// The memory pool class is a simple routine for constant time allocation and deallocation
|
||||
// from a fixed size pool of objects. The class uses a simple array to hold the actual
|
||||
// data, a queue for the free list, and a bit field to mark which spots in the array
|
||||
// are allocated.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_POOL_VS_INC)
|
||||
#define RATL_POOL_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
#if !defined(RATL_QUEUE_VS_INC)
|
||||
#include "queue_vs.h"
|
||||
#endif
|
||||
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
// fixme, this could be made more efficient by keepingtrack of the highest slot ever used
|
||||
// then there is no need to fill the free list
|
||||
template <class T>
|
||||
class pool_root : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
array_base<TStorageTraits> mData;
|
||||
queue_vs<int, CAPACITY> mFree;
|
||||
bits_base<CAPACITY> mUsed;
|
||||
int mSize;
|
||||
|
||||
|
||||
void FillFreeList()
|
||||
{
|
||||
mFree.clear();
|
||||
int i;
|
||||
for (i=0;i<CAPACITY;i++)
|
||||
{
|
||||
mFree.push(i);
|
||||
}
|
||||
}
|
||||
int alloc_low()
|
||||
{
|
||||
assert(mSize<CAPACITY);
|
||||
assert(!mUsed[mFree.top()]);
|
||||
|
||||
int NextIndex = mFree.top(); // Get The First Available Location
|
||||
|
||||
mUsed.set_bit(NextIndex);
|
||||
mFree.pop();
|
||||
mSize ++;
|
||||
return NextIndex;
|
||||
}
|
||||
public:
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
pool_root() : mSize(0)
|
||||
{
|
||||
FillFreeList();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Number Of Objects Allocated
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return (mSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If This Memory Pool Is Empty
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
return (mSize==0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If This Memory Pool Is Full
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
return (mSize==CAPACITY);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constant Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue& value_at_index(int i) const
|
||||
{
|
||||
assert(mUsed[i]);
|
||||
return (mData[i]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue& value_at_index(int i)
|
||||
{
|
||||
assert(mUsed[i]);
|
||||
return (mData[i]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear - Removes all allocation information
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mSize = 0;
|
||||
mUsed.clear();
|
||||
mData.clear();
|
||||
FillFreeList();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check If An Index Has Been Allocated
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool is_used_index(int i) const
|
||||
{
|
||||
return mUsed[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a pointer back to an index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int pointer_to_index(const TTValue *me) const
|
||||
{
|
||||
assert(mSize>0);
|
||||
|
||||
int index=mData.pointer_to_index(me);
|
||||
|
||||
assert(index>=0 && index<CAPACITY);
|
||||
assert(mUsed[index]); // I am disallowing obtaining the index of a freed item
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Convert a pointer back to an index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int pointer_to_index(const TRatlNew *me) const
|
||||
{
|
||||
assert(mSize>0);
|
||||
|
||||
int index=mData.pointer_to_index(me);
|
||||
|
||||
assert(index>=0 && index<CAPACITY);
|
||||
assert(mUsed[index]); // I am disallowing obtaining the index of a freed item
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swap two items based on index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void swap_index(int i,int j)
|
||||
{
|
||||
assert(i>=0 && i<CAPACITY);
|
||||
assert(j>=0 && j<CAPACITY);
|
||||
mData.swap(i,j);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int alloc_index()
|
||||
{
|
||||
int NextIndex = alloc_low();
|
||||
mData.construct(NextIndex);
|
||||
return NextIndex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int alloc_index(const TTValue &v)
|
||||
{
|
||||
int NextIndex = alloc_low();
|
||||
mData.construct(NextIndex,v);
|
||||
return NextIndex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew * alloc_raw()
|
||||
{
|
||||
int NextIndex = alloc_low();
|
||||
return mData.alloc_raw(NextIndex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Deallocator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void free_index(int i)
|
||||
{
|
||||
assert(mSize>0);
|
||||
assert(i>=0 && i<CAPACITY);
|
||||
assert(mUsed[i]);
|
||||
|
||||
mData.destruct(i);
|
||||
|
||||
mUsed.clear_bit(i);
|
||||
mFree.push(i);
|
||||
mSize --;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Deallocator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void free(TTValue *me)
|
||||
{
|
||||
free(pointer_to_index(me));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class const_iterator;
|
||||
class iterator
|
||||
{
|
||||
friend class pool_root<T>;
|
||||
friend class const_iterator;
|
||||
int mIndex;
|
||||
pool_root<T>* mOwner;
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
iterator() : mOwner(0)
|
||||
{}
|
||||
iterator(pool_root<T>* p, int index) : mOwner(p), mIndex(index)
|
||||
{}
|
||||
iterator(const iterator &t) : mOwner(t.mOwner), mIndex(t.mIndex)
|
||||
{}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mIndex = t.mIndex;
|
||||
}
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const iterator& t) {assert(mOwner && mOwner==t.mOwner); return (mIndex!=t.mIndex);}
|
||||
bool operator==(const iterator& t) {assert(mOwner && mOwner==t.mOwner); return (mIndex==t.mIndex);}
|
||||
|
||||
// Dereference Operators
|
||||
//----------------------
|
||||
TTValue& operator* () const {assert(mOwner && mOwner->is_used_index(mIndex)); return (mOwner->mData[mIndex]);}
|
||||
TTValue* operator->() const {assert(mOwner && mOwner->is_used_index(mIndex)); return (&mOwner->mData[mIndex]);}
|
||||
|
||||
// Handle & Index Access
|
||||
//-----------------------
|
||||
int index() {assert(mOwner && mOwner->is_used_index(mIndex)); return mIndex;}
|
||||
|
||||
// Inc Operator
|
||||
//-------------
|
||||
iterator operator++(int) // postfix
|
||||
{
|
||||
assert(mIndex>=0&&mIndex<CAPACITY); // this typically means you did end()++
|
||||
assert(mOwner && mOwner->is_used_index(mIndex));
|
||||
|
||||
iterator ret(*this);
|
||||
mIndex = mOwner->mUsed.next_bit(mIndex+1);
|
||||
return ret;
|
||||
}
|
||||
// Inc Operator
|
||||
//-------------
|
||||
iterator operator++() // prefix
|
||||
{
|
||||
assert(mIndex>=0&&mIndex<CAPACITY); // this typically means you did end()++
|
||||
assert(mOwner && mOwner->is_used_index(mIndex));
|
||||
mIndex = mOwner->mUsed.next_bit(mIndex+1);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
friend class iterator;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class const_iterator
|
||||
{
|
||||
int mIndex;
|
||||
const pool_root<T>* mOwner;
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
const_iterator() : mOwner(0)
|
||||
{}
|
||||
const_iterator(const pool_root<T>* p, int index) : mOwner(p), mIndex(index)
|
||||
{}
|
||||
const_iterator(const iterator &t) : mOwner(t.mOwner), mIndex(t.mIndex)
|
||||
{}
|
||||
const_iterator(const const_iterator &t) : mOwner(t.mOwner), mIndex(t.mIndex)
|
||||
{}
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const const_iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex!=t.mIndex);}
|
||||
bool operator==(const const_iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex==t.mIndex);}
|
||||
bool operator!=(const iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex!=t.mIndex);}
|
||||
bool operator==(const iterator& t) const {assert(mOwner && mOwner==t.mOwner); return (mIndex==t.mIndex);}
|
||||
|
||||
// Dereference Operators
|
||||
//----------------------
|
||||
const TTValue& operator* () const {assert(mOwner && mOwner->is_used_index(mIndex)); return (mOwner->mData[mIndex]);}
|
||||
const TTValue* operator->() const {assert(mOwner && mOwner->is_used_index(mIndex)); return (&mOwner->mData[mIndex]);}
|
||||
|
||||
// Handle & Index Access
|
||||
//-----------------------
|
||||
int index() const {assert(mOwner && mOwner->is_used_index(mIndex)); return mIndex;}
|
||||
|
||||
// Inc Operator
|
||||
//-------------
|
||||
const_iterator operator++(int) // postfix
|
||||
{
|
||||
assert(mIndex>=0&&mIndex<CAPACITY); // this typically means you did end()++
|
||||
assert(mOwner && mOwner->is_used_index(mIndex));
|
||||
|
||||
const_iterator ret(*this);
|
||||
mIndex = mOwner->mUsed.next_bit(mIndex+1);
|
||||
return ret;
|
||||
}
|
||||
// Inc Operator
|
||||
//-------------
|
||||
const_iterator operator++() // prefix
|
||||
{
|
||||
assert(mIndex>=0&&mIndex<CAPACITY); // this typically means you did end()++
|
||||
assert(mOwner && mOwner->is_used_index(mIndex));
|
||||
mIndex = mOwner->mUsed.next_bit(mIndex+1);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
friend class const_iterator;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The First Allocated Memory Block
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator begin()
|
||||
{
|
||||
int idx=mUsed.next_bit(0);
|
||||
return iterator(this,idx); // Find The First Allocated
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The Object At index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator at_index(int index)
|
||||
{
|
||||
assert(mUsed[index]); // disallow iterators to non alloced things
|
||||
return iterator(this, index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The End Of The Memroy (One Step Beyond)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator end()
|
||||
{
|
||||
return iterator(this, CAPACITY);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The First Allocated Memory Block
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator begin() const
|
||||
{
|
||||
int idx=mUsed.next_bit(0);
|
||||
return iterator(this,idx); // Find The First Allocated
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The Object At index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator at_index(int index) const
|
||||
{
|
||||
assert(mUsed[index]); // disallow iterators to non alloced things
|
||||
return iterator(this, index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The End Of The Memroy (One Step Beyond)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator end() const
|
||||
{
|
||||
return iterator(this, CAPACITY);
|
||||
}
|
||||
|
||||
template<class CAST_TO>
|
||||
CAST_TO *verify_alloc(CAST_TO *p) const
|
||||
{
|
||||
return mData.verify_alloc(p);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
pool_base, base class for the pools
|
||||
|
||||
operations:
|
||||
|
||||
size()
|
||||
empty()
|
||||
full()
|
||||
clear() op[]
|
||||
at_index() op[]
|
||||
at_index() const
|
||||
index pointer_to_index(ptr)
|
||||
index alloc_index() alloc()
|
||||
index alloc_index(ref) alloc()
|
||||
ptr alloc_raw()
|
||||
free_index(index)
|
||||
free(ptr)
|
||||
is_used_index(index)
|
||||
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
class pool_base : public pool_root<T>
|
||||
{
|
||||
public:
|
||||
typedef typename T::TValue TTValue;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constant Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue& operator[](int i) const
|
||||
{
|
||||
return value_at_index(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue& operator[](int i)
|
||||
{
|
||||
return value_at_index(i);
|
||||
}
|
||||
|
||||
bool is_used(int i) const
|
||||
{
|
||||
return is_used_index(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swap two items based on index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void swap(int i,int j)
|
||||
{
|
||||
swap_index(i,j);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator returns an index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int alloc()
|
||||
{
|
||||
return alloc_index();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Allocator returns an index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int alloc(const TTValue &v)
|
||||
{
|
||||
return alloc_index(v);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Deallocator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void free(int i)
|
||||
{
|
||||
free_index(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The Object At index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
pool_root<T>::iterator at(int index)
|
||||
{
|
||||
return at_index(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The Object At index
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
pool_root<T>::const_iterator at(int index) const
|
||||
{
|
||||
return at_index(index);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class pool_vs : public pool_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
pool_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class pool_os : public pool_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
pool_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class pool_is : public pool_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
pool_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
231
code/ratl/queue_vs.h
Normal file
231
code/ratl/queue_vs.h
Normal file
@@ -0,0 +1,231 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Queue Template
|
||||
// --------------
|
||||
// The queue is a circular buffer of objects which supports a push at the "front" and a
|
||||
// pop at the "back". Therefore it is:
|
||||
//
|
||||
// First In, First Out
|
||||
//
|
||||
// As the pointers to the push and pop locations are changed it wrapps around the end
|
||||
// of the array and back to the front. There are asserts to make sure it never goes
|
||||
// beyond the capacity of the object.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_QUEUE_VS_INC)
|
||||
#define RATL_QUEUE_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Queue Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <class T>
|
||||
class queue_base : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
array_base<TStorageTraits> mData; // The Memory
|
||||
int mPush; // Address Of Next Add Location
|
||||
int mPop; // Address Of Next Remove Location
|
||||
int mSize;
|
||||
|
||||
|
||||
int push_low()
|
||||
{
|
||||
assert(size()<CAPACITY);
|
||||
|
||||
// Add It
|
||||
//--------
|
||||
mPush++;
|
||||
mSize++;
|
||||
|
||||
// Update Push Location
|
||||
//----------------------
|
||||
if (mPush>=CAPACITY)
|
||||
{
|
||||
mPush=0;
|
||||
return CAPACITY-1;
|
||||
}
|
||||
return mPush-1;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
typedef T TStorageTraits;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
queue_base() : mPush(0), mPop(0), mSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Size (The Difference Between The Push And Pop "Pointers")
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If The Size Is Zero
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
return !mSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If The Size Is Full
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
return mSize>=CAPACITY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Empty Out The Entire Queue
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mPush = 0;
|
||||
mPop = 0;
|
||||
mSize = 0;
|
||||
mData.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value, returns a reference to the value in place
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue & push()
|
||||
{
|
||||
int idx=push_low();
|
||||
mData.construct(idx);
|
||||
return mData[idx];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value to the Queue
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push(const TTValue& v)
|
||||
{
|
||||
mData.construct(push_low(),v);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value to the Queue, returning a void * to the memory
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew *push_raw()
|
||||
{
|
||||
return mData.alloc_raw(push_low());
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove A Value From The Queue
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void pop()
|
||||
{
|
||||
assert(size()>0);
|
||||
|
||||
mData.destruct(mPop);
|
||||
// Update Pop Location
|
||||
//---------------------
|
||||
mPop++;
|
||||
if (mPop>=CAPACITY)
|
||||
{
|
||||
mPop=0;
|
||||
}
|
||||
|
||||
mSize--;
|
||||
}
|
||||
|
||||
TTValue & top()
|
||||
{
|
||||
assert(size()>0);
|
||||
return mData[mPop];
|
||||
}
|
||||
|
||||
const TTValue & top() const
|
||||
{
|
||||
assert(size()>0);
|
||||
return mData[mPop];
|
||||
}
|
||||
template<class CAST_TO>
|
||||
CAST_TO *verify_alloc(CAST_TO *p) const
|
||||
{
|
||||
return mData.verify_alloc(p);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class queue_vs : public queue_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
queue_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class queue_os : public queue_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
queue_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class queue_is : public queue_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
queue_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
130
code/ratl/ratl.cpp
Normal file
130
code/ratl/ratl.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include "array_vs.h"
|
||||
#include "bits_vs.h"
|
||||
#include "heap_vs.h"
|
||||
#include "pool_vs.h"
|
||||
#include "list_vs.h"
|
||||
#include "queue_vs.h"
|
||||
#include "stack_vs.h"
|
||||
#include "string_vs.h"
|
||||
#include "vector_vs.h"
|
||||
#include "handle_pool_vs.h"
|
||||
#include "hash_pool_vs.h"
|
||||
#include "map_vs.h"
|
||||
#include "scheduler_vs.h"
|
||||
#endif
|
||||
|
||||
#if !defined(CTYPE_H_INC)
|
||||
#include <ctype.h>
|
||||
#define CTYPE_H_INC
|
||||
#endif
|
||||
|
||||
#if !defined(STDARG_H_INC)
|
||||
#include <stdarg.h>
|
||||
#define STDARG_H_INC
|
||||
#endif
|
||||
|
||||
#if !defined(STDIO_H_INC)
|
||||
#include <stdio.h>
|
||||
#define STDIO_H_INC
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(RUFL_HFILE_INC)
|
||||
#include "..\Rufl\hfile.h"
|
||||
#endif
|
||||
|
||||
|
||||
void* ratl::ratl_base::OutputPrint = 0;
|
||||
|
||||
|
||||
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
#ifdef _DEBUG
|
||||
int HandleSaltValue=1027; //this is used in debug for global uniqueness of handles
|
||||
int FoolTheOptimizer=5; //this is used to make sure certain things aren't optimized out
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _XBOX
|
||||
void ratl_base::save(hfile& file)
|
||||
{
|
||||
}
|
||||
|
||||
void ratl_base::load(hfile& file)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// A Profile Print Function
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(FINAL_BUILD)
|
||||
void ratl_base::ProfilePrint(const char * format, ...)
|
||||
{
|
||||
static char string[2][1024]; // in case this is called by nested functions
|
||||
static int index = 0;
|
||||
static char nFormat[300];
|
||||
char* buf;
|
||||
|
||||
// Tack On The Standard Format Around The Given Format
|
||||
//-----------------------------------------------------
|
||||
sprintf(nFormat, "[PROFILE] %s\n", format);
|
||||
|
||||
|
||||
// Resolve Remaining Elipsis Parameters Into Newly Formated String
|
||||
//-----------------------------------------------------------------
|
||||
buf = string[index & 1];
|
||||
index++;
|
||||
|
||||
va_list argptr;
|
||||
va_start (argptr, format);
|
||||
vsprintf (buf, nFormat, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
// Print It To Debug Output Console
|
||||
//----------------------------------
|
||||
if (OutputPrint!=0)
|
||||
{
|
||||
void (*OutputPrintFcn)(const char* text) = (void (__cdecl*)(const char*))OutputPrint;
|
||||
OutputPrintFcn(buf);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ratl_base::ProfilePrint(const char * format, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace str
|
||||
{
|
||||
void to_upper(char *dest)
|
||||
{
|
||||
for (int i=0; i<len(dest);i++)
|
||||
{
|
||||
dest[i] = (char)(toupper(dest[i]));
|
||||
}
|
||||
}
|
||||
void to_lower(char *dest)
|
||||
{
|
||||
for (int i=0; i<len(dest);i++)
|
||||
{
|
||||
dest[i] = (char)(tolower(dest[i]));
|
||||
}
|
||||
}
|
||||
void printf(char *dest,const char *formatS, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
va_start (argptr, formatS);
|
||||
vsprintf (dest, formatS,argptr);
|
||||
va_end (argptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1180
code/ratl/ratl_common.h
Normal file
1180
code/ratl/ratl_common.h
Normal file
File diff suppressed because it is too large
Load Diff
218
code/ratl/scheduler_vs.h
Normal file
218
code/ratl/scheduler_vs.h
Normal file
@@ -0,0 +1,218 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Scheduler
|
||||
// ---------
|
||||
// The scheduler is a common piece of game functionality. To use it, simply add events
|
||||
// at the given time, and call update() with the current time as frequently as you wish.
|
||||
//
|
||||
// Your event class MUST define a Fire() function which accepts a TCALLBACKPARAMS
|
||||
// parameter.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_SCHEDULER_VS_INC)
|
||||
#define RATL_SCHEDULER_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
#if !defined(RATL_POOL_VS_INC)
|
||||
#include "pool_vs.h"
|
||||
#endif
|
||||
#if !defined(RATL_HEAP_VS_INC)
|
||||
#include "heap_vs.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Scheduler Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <class T>
|
||||
class scheduler_base : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Timed Event Class
|
||||
//
|
||||
// This class stores two numbers, a timer and an iterator to the events list. We
|
||||
// don't store the event directly in the heap to make the swap operation in the
|
||||
// heap faster. We define a less than operator so we can sort in the heap.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
struct timed_event
|
||||
{
|
||||
float mTime;
|
||||
int mEvent;
|
||||
|
||||
timed_event() {}
|
||||
timed_event(float time, int event) : mTime(time), mEvent(event) {}
|
||||
bool operator< (const timed_event& t) const
|
||||
{
|
||||
return (mTime > t.mTime);
|
||||
}
|
||||
};
|
||||
|
||||
pool_base<TStorageTraits> mEvents;
|
||||
heap_vs<timed_event, CAPACITY> mHeap;
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// How Many Objects Are In This List
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
// warning during a fire call, there will be one extra event
|
||||
return mEvents.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Are There Any Objects In This List?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
return !size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Is This List Filled?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
return mEvents.full();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear All Elements
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mEvents.clear();
|
||||
mHeap.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add An Event
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void add(float time, const TTValue& e)
|
||||
{
|
||||
int nLoc = mEvents.alloc(e);
|
||||
mHeap.push(timed_event(time, nLoc));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add An Event
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue & add(float time)
|
||||
{
|
||||
int nLoc = mEvents.alloc();
|
||||
mHeap.push(timed_event(time, nLoc));
|
||||
return mEvents[nLoc];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Raw Event for placement new
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew * add_raw(float time)
|
||||
{
|
||||
TRatlNew *ret = mEvents.alloc_raw();
|
||||
mHeap.push(timed_event(time, mEvents.pointer_to_index(ret)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class TCALLBACKPARAMS>
|
||||
void update(float time, TCALLBACKPARAMS& Params)
|
||||
{
|
||||
while (!mHeap.empty())
|
||||
{
|
||||
timed_event Next = mHeap.top();
|
||||
if (Next.mTime>=time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
mHeap.pop();
|
||||
mEvents[Next.mEvent].Fire(Params);
|
||||
mEvents.free(Next.mEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void update(float time)
|
||||
{
|
||||
while (!mHeap.empty())
|
||||
{
|
||||
timed_event Next = mHeap.top();
|
||||
if (Next.mTime>=time)
|
||||
{
|
||||
break;
|
||||
}
|
||||
mHeap.pop();
|
||||
mEvents[Next.mEvent].Fire();
|
||||
mEvents.free(Next.mEvent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class scheduler_vs : public scheduler_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
scheduler_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class scheduler_os : public scheduler_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
scheduler_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class scheduler_is : public scheduler_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
scheduler_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
197
code/ratl/stack_vs.h
Normal file
197
code/ratl/stack_vs.h
Normal file
@@ -0,0 +1,197 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Stack
|
||||
// -----
|
||||
// This is a very simple wrapper around a stack object.
|
||||
//
|
||||
// First In, Last Out
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_STACK_VS_INC)
|
||||
#define RATL_STACK_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The stack Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <class T>
|
||||
class stack_base : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
array_base<TStorageTraits> mData; // The Memory
|
||||
int mSize;
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
stack_base() : mSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get The Size (The Difference Between The Push And Pop "Pointers")
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If The Size Is Zero
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
return !mSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Check To See If The Size Is Full
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
return mSize>=CAPACITY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Empty Out The Entire stack
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mSize = 0;
|
||||
mData.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value, returns a reference to the value in place
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue & push()
|
||||
{
|
||||
assert(!full());
|
||||
mData.construct(mSize);
|
||||
mSize++;
|
||||
return mData[mSize-1];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value to the stack
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push(const TTValue& v)
|
||||
{
|
||||
assert(!full());
|
||||
mData.construct(mSize,v);
|
||||
mSize++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add A Value to the stack, returning a void * to the memory
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew *push_raw()
|
||||
{
|
||||
assert(!full());
|
||||
mSize++;
|
||||
return mData.alloc_raw(mSize-1);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove A Value From The stack
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void pop()
|
||||
{
|
||||
assert(!empty());
|
||||
mSize--;
|
||||
mData.destruct(mSize);
|
||||
}
|
||||
|
||||
TTValue & top()
|
||||
{
|
||||
assert(!empty());
|
||||
return mData[mSize-1];
|
||||
}
|
||||
|
||||
const TTValue & top() const
|
||||
{
|
||||
assert(!empty());
|
||||
return mData[mSize-1];
|
||||
}
|
||||
template<class CAST_TO>
|
||||
CAST_TO *verify_alloc(CAST_TO *p) const
|
||||
{
|
||||
return mData.verify_alloc(p);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class stack_vs : public stack_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
stack_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class stack_os : public stack_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
stack_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class stack_is : public stack_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
stack_is() {}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
366
code/ratl/string_vs.h
Normal file
366
code/ratl/string_vs.h
Normal file
@@ -0,0 +1,366 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// String
|
||||
// ------
|
||||
// Simple wrapper around a char[SIZE] array.
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_STRING_VS_INC)
|
||||
#define RATL_STRING_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The String Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<int ARG_CAPACITY>
|
||||
class string_vs : public ratl_base
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
};
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _DEBUG
|
||||
char mData[CAPACITY+4];
|
||||
#else
|
||||
char mData[CAPACITY];
|
||||
#endif
|
||||
|
||||
void FillTerminator()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
mData[CAPACITY]='e';
|
||||
mData[CAPACITY+1]='n';
|
||||
mData[CAPACITY+2]='d';
|
||||
mData[CAPACITY+3]=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs()
|
||||
{
|
||||
mData[0]=0;
|
||||
FillTerminator();
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
~string_vs()
|
||||
{
|
||||
//if you hit the below asserts, the end of the string was overwritten
|
||||
assert(mData[CAPACITY]=='e');
|
||||
assert(mData[CAPACITY+1]=='n');
|
||||
assert(mData[CAPACITY+2]=='d');
|
||||
assert(mData[CAPACITY+3]==0);
|
||||
}
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs(const string_vs<CAPACITY> &o)
|
||||
{
|
||||
assert(str::len(o.mData)<CAPACITY);
|
||||
str::ncpy(mData, o.mData, CAPACITY); // Safe String Copy
|
||||
mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
FillTerminator();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs(const char *s)
|
||||
{
|
||||
assert(str::len(s)<CAPACITY);
|
||||
str::ncpy(mData, s, CAPACITY); // Safe String Copy
|
||||
mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
FillTerminator();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
string_vs& operator=(const char *s)
|
||||
{
|
||||
assert(str::len(s)<CAPACITY);
|
||||
str::ncpy(mData, s, CAPACITY); // Safe String Copy
|
||||
mData[CAPACITY-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
FillTerminator();
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
char* c_str()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const char* c_str() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
operator const char *()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To Raw Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const char* operator*()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// How Many Characters Can This Hold
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int capacity() const
|
||||
{
|
||||
return CAPACITY;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Length
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int length() const
|
||||
{
|
||||
assert(str::len(mData)<CAPACITY-1);
|
||||
return str::len(mData);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Character Bracket Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
char operator[](int index)
|
||||
{
|
||||
assert(index<CAPACITY);
|
||||
return mData[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Equality Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator==(const string_vs &o) const
|
||||
{
|
||||
if (!stricmp(mData,o.mData))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// InEquality Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator!=(const string_vs &o) const
|
||||
{
|
||||
if (str::icmp(mData,o.mData)!=0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compare Less Than
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator<(const string_vs &o) const
|
||||
{
|
||||
if (str::icmp(mData,o.mData)<0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compare Greater Than
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool operator>(const string_vs &o) const
|
||||
{
|
||||
if (str::icmp(mData,o.mData)>0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator+=(const string_vs &o)
|
||||
{
|
||||
if ( (str::len(mData)+o.length())<CAPACITY ) // Only If It Is Safe
|
||||
{
|
||||
str::cat(mData, o.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"string_vs overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void operator+=(const char *s)
|
||||
{
|
||||
if ( (str::len(mData)+str::len(s))<CAPACITY ) // Only If It Is Safe
|
||||
{
|
||||
str::cat(mData, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"string_vs overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Tokenizer
|
||||
//
|
||||
// The string tokenizer class is similar to an iterator in that it essentially
|
||||
// iterates over all the tokens in the string seperated by a common series of
|
||||
// delinating sequences. For example: " ,\t\n" would seperate tokens on spaces
|
||||
// commas, tabs and linefeeds.
|
||||
//
|
||||
// Iterating over string tokens is just like normal iteration:
|
||||
//
|
||||
// for (string_vs<CAPACITY>::tokenizer it=MyString.begin(" ,\t\n"); it!=MyString.end(); it++)
|
||||
// {
|
||||
// const char* token = *it;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// NOTE: This class is built upon the c library function strtok() which uses a
|
||||
// static working area, so having multiple tokenizers in multiple threads or just
|
||||
// plain at the same time is not safe.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class tokenizer
|
||||
{
|
||||
enum
|
||||
{
|
||||
TOKEN_GAP_LEN = 15,
|
||||
};
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
tokenizer() : mLoc(0)
|
||||
{}
|
||||
tokenizer(const char* t, const char* gap)
|
||||
{
|
||||
strncpy(mGap, gap, TOKEN_GAP_LEN); // Safe String Copy
|
||||
mGap[TOKEN_GAP_LEN-1] = 0; // Make Sure We Have A Null Terminated Str
|
||||
|
||||
char* temp = (char*)t;
|
||||
mLoc = str::tok(temp, mGap);
|
||||
}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const tokenizer &t)
|
||||
{
|
||||
mLoc = t.mLoc;
|
||||
str::cpy(mGap, t.mGap);
|
||||
}
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator==(const tokenizer &t) {return (mLoc==t.mLoc);}
|
||||
bool operator!=(const tokenizer &t) {return !(operator==(t));}
|
||||
|
||||
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const char* operator*()
|
||||
{
|
||||
assert(mLoc);
|
||||
return mLoc;
|
||||
}
|
||||
|
||||
// Inc & Dec Operators
|
||||
//--------------------
|
||||
void operator++(int)
|
||||
{
|
||||
assert(mLoc && mGap[0]);
|
||||
mLoc = str::tok(NULL, mGap);
|
||||
}
|
||||
|
||||
// Data
|
||||
//------
|
||||
private:
|
||||
char* mLoc;
|
||||
char mGap[TOKEN_GAP_LEN];
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Get An Iterator To The First Token Seperated By Gap
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
tokenizer begin(const char* gap)
|
||||
{
|
||||
return tokenizer(mData, gap);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Invalid Iterator, Use As A Stop Condition In Your For Loops
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
tokenizer end()
|
||||
{
|
||||
return tokenizer();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
//fixme get rid of these
|
||||
typedef ratl::string_vs<256> TString_vs;
|
||||
typedef ratl::string_vs<128> TUIString_vs;
|
||||
|
||||
#endif
|
||||
757
code/ratl/vector_vs.h
Normal file
757
code/ratl/vector_vs.h
Normal file
@@ -0,0 +1,757 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN STANDARD TEMPLATE LIBRARY
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
//
|
||||
// Vector
|
||||
// ------
|
||||
// The vector class is a simple addition to the array. It supports some useful additions
|
||||
// like sort and binary search, as well as keeping track of the number of objects
|
||||
// contained within.
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_VECTOR_VS_INC)
|
||||
#define RATL_VECTOR_VS_INC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(RATL_COMMON_INC)
|
||||
#include "ratl_common.h"
|
||||
#endif
|
||||
namespace ratl
|
||||
{
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The Vector Class
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
class vector_base : public ratl_base
|
||||
{
|
||||
public:
|
||||
typedef typename T TStorageTraits;
|
||||
typedef typename T::TValue TTValue;
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Capacity Enum
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CAPACITY = T::CAPACITY
|
||||
};
|
||||
private:
|
||||
array_base<TStorageTraits> mArray; // The Memory
|
||||
int mSize;
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
vector_base()
|
||||
{
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copy Constructor
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
vector_base(const vector_base &B)
|
||||
{
|
||||
for (int i=0; i<B.size(); i++)
|
||||
{
|
||||
mArray[i] = B.mArray[i];
|
||||
}
|
||||
mSize = val.mSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// How Many Objects Can Be Added?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int capacity() const
|
||||
{
|
||||
assert(mSize>=0&&mSize<=CAPACITY);
|
||||
return (CAPACITY);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// How Many Objects Have Been Added To This Vector?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int size() const
|
||||
{
|
||||
assert(mSize>=0&&mSize<=CAPACITY);
|
||||
return (mSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Have Any Objects Have Been Added To This Vector?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool empty() const
|
||||
{
|
||||
assert(mSize>=0&&mSize<=CAPACITY);
|
||||
return (!mSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Have Any Objects Have Been Added To This Vector?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
bool full() const
|
||||
{
|
||||
assert(mSize>=0&&mSize<=CAPACITY);
|
||||
return (mSize==CAPACITY);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Clear Out Entire Array
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void clear()
|
||||
{
|
||||
mArray.clear();
|
||||
mSize = 0;
|
||||
}
|
||||
// Constant Access Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue& operator[](int index) const
|
||||
{
|
||||
assert(index>=0&&index<mSize);
|
||||
return mArray[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue& operator[](int index)
|
||||
{
|
||||
assert(index>=0&&index<mSize);
|
||||
return mArray[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To The Raw Array Pointer
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue * raw_array()
|
||||
{
|
||||
// this (intentionally) won't compile for anything except value semantics
|
||||
// could be done with object semantics, but I would want to assert that all objects are contructed
|
||||
return T::raw_array(mArray);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Access To The Raw Array Pointer
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const TTValue* raw_array() const
|
||||
{
|
||||
// this (intentionally) won't compile for anything except value semantics
|
||||
// could be done with object semantics, but I would want to assert that all objects are contructed
|
||||
return T::raw_array(mArray);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Assignment Operator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
vector_base& operator=(const vector_base& val)
|
||||
{
|
||||
for (int i=0; i<val.size(); i++)
|
||||
{
|
||||
mArray[i] = val.mArray[i];
|
||||
}
|
||||
mSize = val.mSize;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TTValue & push_back()
|
||||
{
|
||||
assert(mSize>=0&&mSize<CAPACITY);
|
||||
mArray.construct(mSize);
|
||||
mSize++;
|
||||
return (mArray[mSize-1]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add (And Set)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void push_back(const TTValue& value)
|
||||
{
|
||||
assert(mSize>=0&&mSize<CAPACITY);
|
||||
mArray.construct(mSize,value);
|
||||
mSize++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add raw
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
TRatlNew * push_back_raw()
|
||||
{
|
||||
assert(mSize>=0&&mSize<CAPACITY);
|
||||
mSize++;
|
||||
return mArray.alloc_raw(mSize-1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void pop_back()
|
||||
{
|
||||
assert(mSize>0);
|
||||
mSize--;
|
||||
mArray.destruct(mSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Resizes The Array. If New Elements Are Needed, It Uses The (value) Param
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void resize(int nSize, const TTValue& value)
|
||||
{
|
||||
int i;
|
||||
for (i=(mSize-1); i>=nSize; i--)
|
||||
{
|
||||
mArray.destruct(i);
|
||||
mSize--;
|
||||
}
|
||||
for (i=mSize; i<nSize; i++)
|
||||
{
|
||||
mArray.construct(i,value);
|
||||
}
|
||||
mSize = nSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Resizes The Array. If New Elements Are Needed, It Uses The (value) Param
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void resize(int nSize)
|
||||
{
|
||||
int i;
|
||||
for (i=mSize-1; i>=nSize; i--)
|
||||
{
|
||||
mArray.destruct(i);
|
||||
mSize--;
|
||||
}
|
||||
for (i=mSize; i<nSize; i++)
|
||||
{
|
||||
mArray.construct(i);
|
||||
}
|
||||
mSize = nSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Swap the values at two locations
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void swap(int i,int j)
|
||||
{
|
||||
assert(i<mSize && j<mSize);
|
||||
mArray.swap(i, j);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Erase An Iterator Location... NOTE: THIS DOES NOT PRESERVE ORDER IN THE VECTOR!!
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void erase_swap(int Index)
|
||||
{
|
||||
assert(Index>=0 && Index<mSize);
|
||||
if (Index != mSize - 1)
|
||||
{
|
||||
mArray.swap(Index, mSize - 1);
|
||||
}
|
||||
pop_back();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Binary Search
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int find_index(const TTValue& value) const
|
||||
{
|
||||
int base = 0;
|
||||
int head = mSize-1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int searchAt = (base+head)/2;
|
||||
|
||||
if (base == head && searchAt == head)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (value < mArray[searchAt])
|
||||
{
|
||||
head = searchAt-1;
|
||||
}
|
||||
else if (mArray[searchAt] < value)
|
||||
{
|
||||
base = searchAt;
|
||||
}
|
||||
else
|
||||
{
|
||||
return searchAt;
|
||||
}
|
||||
if (head < base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mSize; //not found!
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Heap Sort
|
||||
//
|
||||
// This sort algorithm has all the advantages of merge sort in terms of guarenteeing
|
||||
// O(n log n) worst case, as well as all the advantages of quick sort in that it is
|
||||
// "in place" and requires no additional storage.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
void sort()
|
||||
{
|
||||
// Temporary Data
|
||||
//----------------
|
||||
int HeapSize; // How Large The Heap Is (Grows In PHASE 1, Shrinks In PHASE 2)
|
||||
int Pos; // The Location We Are AT During "re-heapify" Loops
|
||||
int Compare; // The Location We Are Comparing AGAINST During "re-heapify" Loops
|
||||
|
||||
|
||||
|
||||
|
||||
// PHASE 1, CONSTRUCT THE HEAP O(n log n)
|
||||
//===============================================================================
|
||||
for (HeapSize=1; HeapSize<mSize; HeapSize++)
|
||||
{
|
||||
// We Now Have An Element At Heap Size Which Is Not In It's Correct Place
|
||||
//------------------------------------------------------------------------
|
||||
Pos = HeapSize;
|
||||
Compare = parent(Pos);
|
||||
while (mArray[Compare]<mArray[Pos])
|
||||
{
|
||||
// Swap The Compare Element With The Pos Element
|
||||
//-----------------------------------------------
|
||||
mArray.swap(Compare, Pos);
|
||||
|
||||
// Move Pos To The Current Compare, And Recalc Compare
|
||||
//------------------------------------------------------
|
||||
Pos = Compare;
|
||||
Compare = parent(Pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// PHASE 2, POP OFF THE TOP OF THE HEAP ONE AT A TIME (AND FIX) O(n log n)
|
||||
//===============================================================================
|
||||
for (HeapSize=(mSize-1); HeapSize>0; HeapSize--)
|
||||
{
|
||||
// Swap The End And Front Of The "Heap" Half Of The Array
|
||||
//--------------------------------------------------------
|
||||
mArray.swap(0, HeapSize);
|
||||
|
||||
// We Now Have A Bogus Element At The Root, So Fix The Heap
|
||||
//----------------------------------------------------------
|
||||
Pos = 0;
|
||||
Compare = largest_child(Pos, HeapSize);
|
||||
while (mArray[Pos]<mArray[Compare])
|
||||
{
|
||||
// Swap The Compare Element With The Pos Element
|
||||
//-----------------------------------------------
|
||||
mArray.swap(Compare, Pos);
|
||||
|
||||
// Move Pos To The Current Compare, And Recalc Compare
|
||||
//------------------------------------------------------
|
||||
Pos = Compare;
|
||||
Compare = largest_child(Pos, HeapSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// THIS IS A QUICK VALIDATION OF A SORTED LIST
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _DEBUG
|
||||
void sort_validate() const
|
||||
{
|
||||
for (int a=0; a<(mSize-1); a++)
|
||||
{
|
||||
assert(mArray[a] < mArray[a+1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Heap Sort
|
||||
// Returns The Location Of Node (i)'s Parent Node (The Parent Node Of Zero Is Zero)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
static int parent(int i)
|
||||
{
|
||||
return ((i-1)/2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Heap Sort
|
||||
// Returns The Location Of Node (i)'s Left Child (The Child Of A Leaf Is The Leaf)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
static int left(int i)
|
||||
{
|
||||
return ((2*i)+1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Heap Sort
|
||||
// Returns The Location Of Node (i)'s Right Child (The Child Of A Leaf Is The Leaf)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
static int right(int i)
|
||||
{
|
||||
return ((2*i)+2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// For Heap Sort
|
||||
// Returns The Location Of Largest Child Of Node (i)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
int largest_child(int i, int Size) const
|
||||
{
|
||||
if (left(i)<Size)
|
||||
{
|
||||
if (right(i)<Size)
|
||||
{
|
||||
return ( (mArray[right(i)] < mArray[left(i)]) ? (left(i)) : (right(i)) );
|
||||
}
|
||||
return left(i); // Node i only has a left child, so by default it is the biggest
|
||||
}
|
||||
return i; // Node i is a leaf, so just return it
|
||||
}
|
||||
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class const_iterator;
|
||||
class iterator
|
||||
{
|
||||
friend class vector_base<T>;
|
||||
friend class const_iterator;
|
||||
// Data
|
||||
//------
|
||||
int mLoc;
|
||||
vector_base<T>* mOwner;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
iterator() : mOwner(0), mLoc(0)
|
||||
{}
|
||||
iterator(vector_base<T>* p, int t) : mOwner(p), mLoc(t)
|
||||
{}
|
||||
|
||||
iterator(const iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc)
|
||||
{}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mLoc = t.mLoc;
|
||||
}
|
||||
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const iterator &t) const
|
||||
{
|
||||
return (mLoc!=t.mLoc || mOwner!=t.mOwner);
|
||||
}
|
||||
bool operator==(const iterator &t) const
|
||||
{
|
||||
return (mLoc==t.mLoc && mOwner==t.mOwner);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
TTValue& operator* () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
return (mOwner->mArray[mLoc]);
|
||||
}
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
TTValue& value() const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
return (mOwner->mArray[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
TTValue* operator-> () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
return (&mOwner->mArray[mLoc]);
|
||||
}
|
||||
|
||||
// Inc Operator
|
||||
//--------------
|
||||
iterator operator++(int) //postfix
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
iterator old(*this);
|
||||
mLoc ++;
|
||||
return old;
|
||||
}
|
||||
|
||||
// Inc Operator
|
||||
//--------------
|
||||
iterator operator++()
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
mLoc ++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constant Iterator
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
class const_iterator
|
||||
{
|
||||
friend class vector_base<T>;
|
||||
|
||||
int mLoc;
|
||||
const vector_base<T>* mOwner;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
//--------------
|
||||
const_iterator() : mOwner(0), mLoc(0)
|
||||
{}
|
||||
const_iterator(const vector_base<T>* p, int t) : mOwner(p), mLoc(t)
|
||||
{}
|
||||
const_iterator(const const_iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc)
|
||||
{}
|
||||
const_iterator(const iterator &t) : mOwner(t.mOwner), mLoc(t.mLoc)
|
||||
{}
|
||||
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const const_iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mLoc = t.mLoc;
|
||||
}
|
||||
// Assignment Operator
|
||||
//---------------------
|
||||
void operator= (const iterator &t)
|
||||
{
|
||||
mOwner = t.mOwner;
|
||||
mLoc = t.mLoc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const iterator &t) const
|
||||
{
|
||||
return (mLoc!=t.mLoc || mOwner!=t.mOwner);
|
||||
}
|
||||
bool operator==(const iterator &t) const
|
||||
{
|
||||
return (mLoc==t.mLoc && mOwner==t.mOwner);
|
||||
}
|
||||
|
||||
// Equality Operators
|
||||
//--------------------
|
||||
bool operator!=(const const_iterator &t) const
|
||||
{
|
||||
return (mLoc!=t.mLoc || mOwner!=t.mOwner);
|
||||
}
|
||||
bool operator==(const const_iterator &t) const
|
||||
{
|
||||
return (mLoc==t.mLoc && mOwner==t.mOwner);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const TTValue& operator* () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
return (mOwner->mArray[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const TTValue& value() const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
return (mOwner->mArray[mLoc]);
|
||||
}
|
||||
|
||||
// DeReference Operator
|
||||
//----------------------
|
||||
const TTValue* operator-> () const
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
return (&mOwner->mArray[mLoc]);
|
||||
}
|
||||
|
||||
// Inc Operator
|
||||
//--------------
|
||||
const_iterator operator++(int)
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
const_iterator old(*this);
|
||||
mLoc ++;
|
||||
return old;
|
||||
}
|
||||
|
||||
// Inc Operator
|
||||
//--------------
|
||||
const_iterator operator++()
|
||||
{
|
||||
assert(mLoc>=0 && mLoc<mOwner->mSize);
|
||||
mLoc ++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Begin (Starts At Address 0)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(this, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator End (Set To Address mSize)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator end()
|
||||
{
|
||||
return iterator(this, mSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Begin (Starts At Address 0)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(this, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator End (Set To Address mSize)
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(this, mSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Find (If Fails To Find, Returns iterator end()
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator find(const TTValue& value)
|
||||
{
|
||||
int index = find_index(value); // Call Find By Index
|
||||
if (index<mSize)
|
||||
{
|
||||
return iterator(this, index); // Found It, Return An Iterator To Index
|
||||
}
|
||||
return end(); // Return "end" Iterator If Not Found
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator Find (If Fails To Find, Returns iterator end()
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
const_iterator find(const TTValue& value) const
|
||||
{
|
||||
int index = find_index(value); // Call Find By Index
|
||||
if (index<mSize)
|
||||
{
|
||||
return const_iterator(this, index); // Found It, Return An Iterator To Index
|
||||
}
|
||||
return end(); // Return "end" Iterator If Not Found
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Erase An Iterator Location... NOTE: THIS DOES NOT PRESERVE ORDER IN THE VECTOR!!
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
iterator erase_swap(const iterator &it)
|
||||
{
|
||||
assert(it.mLoc>=0 && it.mLoc<it.mOwner->mSize);
|
||||
if (it.mLoc != mSize - 1)
|
||||
{
|
||||
mArray.swap(it.mLoc, mSize - 1);
|
||||
}
|
||||
pop_back();
|
||||
return it;
|
||||
}
|
||||
template<class CAST_TO>
|
||||
CAST_TO *verify_alloc(CAST_TO *p) const
|
||||
{
|
||||
return mArray.verify_alloc(p);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class vector_vs : public vector_base<storage::value_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
vector_vs() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY>
|
||||
class vector_os : public vector_base<storage::object_semantics<T,ARG_CAPACITY> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY
|
||||
};
|
||||
vector_os() {}
|
||||
};
|
||||
|
||||
template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
|
||||
class vector_is : public vector_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
|
||||
{
|
||||
public:
|
||||
typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
|
||||
typedef typename TStorageTraits::TValue TTValue;
|
||||
enum
|
||||
{
|
||||
CAPACITY = ARG_CAPACITY,
|
||||
MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
|
||||
};
|
||||
vector_is() {}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user