mirror of
https://github.com/ioquake/jedi-academy.git
synced 2024-11-10 07:11:44 +00:00
758 lines
21 KiB
C
758 lines
21 KiB
C
|
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// 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
|