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