Initial commit.

This commit is contained in:
Jim Gray
2013-04-04 14:32:05 -07:00
parent ba5c81da32
commit d71d53e8ec
2180 changed files with 1393544 additions and 1 deletions

73
code/ratl/array_vs.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

570
code/ratl/pool_vs.h Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

218
code/ratl/scheduler_vs.h Normal file
View 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
View 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
View 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
View 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