jediacademy/code/Ratl/list_vs.h

751 lines
21 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////
// 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