1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630 |
- ////////////////////////////////////////////////////////////////////////////////////////
- // RAVEN STANDARD TEMPLATE LIBRARY
- // (c) 2002 Activision
- //
- //
- // Map
- // ---
- // This map is based on a red black tree, which guarentees balanced data, no mater what
- // order elements are added. The map uses a memory pool for storage of node data.
- //
- //
- ////////////////////////////////////////////////////////////////////////////////////////
- #if !defined(RATL_MAP_VS_INC)
- #define RATL_MAP_VS_INC
- ////////////////////////////////////////////////////////////////////////////////////////
- // Includes
- ////////////////////////////////////////////////////////////////////////////////////////
- #if defined(RA_DEBUG_LINKING)
- #pragma message("...including map_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 set, but you have no access to it, soooo..
-
- class tree_node
- {
- int mParent;
- int mLeft;
- int mRight;
- public:
- enum
- {
- RED_BIT = 0x40000000, // to save space we are putting the red bool in a high bit
- // this is in the parent only
- NULL_NODE = 0x3fffffff, // this must not have the red bit set
- };
- void init()
- {
- mLeft = NULL_NODE;
- mRight = NULL_NODE;
- mParent = NULL_NODE | RED_BIT;
- }
- int left() const
- {
- return mLeft;
- }
- int right() const
- {
- return mRight;
- }
- int parent() const
- {
- return mParent & (~RED_BIT);
- }
- bool red() const
- {
- return !!(mParent & RED_BIT);
- }
- void set_left(int l)
- {
- mLeft = l;
- }
- void set_right(int r)
- {
- mRight = r;
- }
- void set_parent(int p)
- {
- mParent &= RED_BIT;
- mParent |= p;
- }
- void set_red(bool isRed)
- {
- if (isRed)
- {
- mParent |= RED_BIT;
- }
- else
- {
- mParent &= ~RED_BIT;
- }
- }
- };
- //fixme void *, comparison function pointer-ize this for code bloat.
- template<class T, int IS_MULTI>
- class tree_base
- {
- public:
- typedef typename T TStorageTraits;
- typedef typename T::TValue TTValue;
- ////////////////////////////////////////////////////////////////////////////////////
- // Capacity Enum
- ////////////////////////////////////////////////////////////////////////////////////
- enum
- {
- CAPACITY = T::CAPACITY,
- };
- private:
- pool_base<TStorageTraits> mPool; // The Allocation Data Pool
- int mRoot;
- int mLastAdd;
- void link_left(int node,int left)
- {
- T::node(mPool[node]).set_left(left);
- if (left!=tree_node::NULL_NODE)
- {
- T::node(mPool[left]).set_parent(node);
- }
- }
- void link_right(int node,int right)
- {
- T::node(mPool[node]).set_right(right);
- if (right!=tree_node::NULL_NODE)
- {
- T::node(mPool[right]).set_parent(node);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive find function - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int find_internal(const TTValue &key, int at) const
- {
- // FAIL TO FIND?
- //---------------
- if (at==tree_node::NULL_NODE)
- {
- return tree_node::NULL_NODE;
- }
- // Should We Search Left?
- //------------------------
- if (key<mPool[at])
- {
- return find_internal(key, T::node(mPool[at]).left());
- }
- // Should We Search Right?
- //------------------------
- else if (mPool[at]<key)
- {
- return find_internal(key, T::node(mPool[at]).right());
- }
- // FOUND!
- //--------
- return at;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive find function - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int find_internal(const TTValue &key, int target, int at, int& parent) const
- {
- // FAIL TO FIND?
- //---------------
- if (at==tree_node::NULL_NODE)
- {
- parent = tree_node::NULL_NODE;
- return tree_node::NULL_NODE;
- }
- // FOUND!
- //--------
- if (at==target)
- {
- if (at==mRoot)
- {
- parent = tree_node::NULL_NODE;
- }
- return at;
- }
- // Should We Search Left?
- //------------------------
- if (key<mPool[at])
- {
- parent = at;
- return find_internal(key, target, T::node(mPool[at]).left(), parent);
- }
- parent = at;
- return find_internal(key, target, T::node(mPool[at]).right(), parent);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive insertion - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int insert_internal(const TTValue &key, int &at)
- {
- // If At Is A NULL_NODE, We Have Found A Leaf.
- //----------------------------------------------
- if (at==tree_node::NULL_NODE)
- {
- if (mRoot==tree_node::NULL_NODE)
- {
- mRoot = mLastAdd;
- }
- return tree_node::NULL_NODE; // There Are No Excess Red Children (No Childeren At All, Actually)
- }
- int nxtChild; // The Child We Will Eventually Add Underneath
- int altChild; // The "other" Child
- bool nxtRotateLeft;
- int excessRedChild; // If The Insert Results In An Excess Red Child, This Will Be It
- // Choose Which Side To Add The New Node Under
- //---------------------------------------------
- if (key < mPool[at]) // The Key Classes Must Support A < Operator
- {
- int tmp=T::node(mPool[at]).left();
- excessRedChild = insert_internal(key,tmp);
- link_left(at,tmp);//T::node(mPool[at]).set_left(tmp);
- if (tmp==tree_node::NULL_NODE)
- {
- link_left(at,mLastAdd);//T::node(mPool[at]).set_left(mLastAdd); // If mLeft Of The Current Node Is NULL, We Must Have Added DIRECTLY Below nAt
- }
- nxtChild = T::node(mPool[at]).left();
- altChild = T::node(mPool[at]).right();
- nxtRotateLeft = false;
- }
- else if (mPool[at] < key)
- {
- int tmp=T::node(mPool[at]).right();
- excessRedChild = insert_internal(key,tmp);
- link_right(at,tmp); // T::node(mPool[at]).set_right(tmp);
- if (tmp==tree_node::NULL_NODE)
- {
- link_right(at,mLastAdd); // T::node(mPool[at]).set_right(mLastAdd); // If mRight Of The Current Node Is NULL, We Must Have Added DIRECTLY Below nAt
- }
- nxtChild = T::node(mPool[at]).right();
- altChild = T::node(mPool[at]).left();
- nxtRotateLeft = true;
- }
- // Exact Match
- //-------------
- else
- {
- // the node of interest is at
- return tree_node::NULL_NODE;
- }
-
- // If The Add Resulted In An Excess Red Child, We Need To Change Colors And Rotate
- //---------------------------------------------------------------------------------
- if (excessRedChild!=tree_node::NULL_NODE)
- {
- // If Both Childeren Are Red, Just Switch And Be Done
- //----------------------------------------------------
- if (T::node(mPool[at]).right()!=tree_node::NULL_NODE &&
- T::node(mPool[at]).left()!=tree_node::NULL_NODE &&
- T::node(mPool[T::node(mPool[at]).right()]).red() &&
- T::node(mPool[T::node(mPool[at]).left()]).red())
- {
- set_colors(T::node(mPool[at]), true, false);
- }
- else
- {
- int excessRedChildCompare =
- (nxtRotateLeft)?(T::node(mPool[nxtChild]).right()):(T::node(mPool[nxtChild]).left());
- if (excessRedChild==excessRedChildCompare)
- {
- // Single Rotation
- //-----------------
- rotate(at, nxtRotateLeft);
- }
- else
- {
- if (nxtRotateLeft)
- {
- int nxt=T::node(mPool[at]).right();
- rotate(nxt, false);
- link_right(at,nxt); // T::node(mPool[at]).set_right(nxt);
- }
- else
- {
- int nxt=T::node(mPool[at]).left();
- rotate(nxt,true);
- link_left(at,nxt); // T::node(mPool[at]).set_left(nxt);
- }
- rotate(at, nxtRotateLeft);
- }
- set_colors(T::node(mPool[at]), false, true);
- }
- }
-
- if (T::node(mPool[at]).red())
- {
- if (T::node(mPool[at]).left()!=tree_node::NULL_NODE &&
- T::node(mPool[T::node(mPool[at]).left()]).red())
- {
- return T::node(mPool[at]).left();
- }
- if (T::node(mPool[at]).right()!=tree_node::NULL_NODE &&
- T::node(mPool[T::node(mPool[at]).right()]).red())
- {
- return T::node(mPool[at]).right();
- }
- }
- return tree_node::NULL_NODE;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive erase - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- bool erase_internal(const TTValue &key, int& at)
- {
- // If At Is A NULL_NODE, We Have Found A Leaf.
- //---------------------------------------------
- if (at==tree_node::NULL_NODE)
- {
- return true;
- }
- //==============================================================================
- // Now The Question Is, Do We Need To Continue Searching?
- //==============================================================================
- // Recurse To The Left?
- //----------------------
- if (key < mPool[at])
- {
- int a=T::node(mPool[at]).left();
- bool r=erase_internal(key, a);
- link_left(at,a); // T::node(mPool[at]).set_left(a);
- if (!r) // If It Was Not Red, We Need To Rebalance
- {
- return rebalance(at, true);
- }
- return true;
- }
- // Recurse To The Right?
- //-----------------------
- if (mPool[at] < key)
- {
- int a=T::node(mPool[at]).right();
- bool r=erase_internal(key, a);
- link_right(at,a); // T::node(mPool[at]).set_right(a);
- if (!r) // If It Was Not Red, We Need To Rebalance
- {
- return rebalance(at, false);
- }
- return true;
- }
- //==============================================================================
- // At This Point, We Must Have Discovered An Exact Match For Our Key
- //==============================================================================
- // Are There Any Open Childeren Slots?
- //-------------------------------------
- if (T::node(mPool[at]).left()==tree_node::NULL_NODE || T::node(mPool[at]).right()==tree_node::NULL_NODE)
- {
- bool atWasRed = T::node(mPool[at]).red();
- int oldAt = at;
- at = (T::node(mPool[at]).left()==tree_node::NULL_NODE)?(T::node(mPool[at]).right()):(T::node(mPool[at]).left()); // If Left Is Null, At Goes Right
- // Actually Free It!
- //-------------------
- mPool.free(oldAt);
- // If We Are Now At A Null Node, Just Return
- //-------------------------------------------
- if (at==tree_node::NULL_NODE)
- {
- return atWasRed;
- }
- // Otherwise, Mark The New Child As Red, And Return That Fact Up
- //---------------------------------------------------------------
- T::node(mPool[at]).set_red(false);
- return true;
- }
- //==============================================================================
- // There Are No Childeren To Link With, We Are In The Middle Of The Tree.
- // We Need To Find An Open Leaf, Swap Data With That Leaf, and Then Go Find It
- //==============================================================================
- // Find A Successor Leaf
- //-----------------------
- int at_parent = T::node(mPool[at]).parent();
- int successor = T::node(mPool[at]).right();
- int parent_successor=-1;
- while(T::node(mPool[successor]).left()!=tree_node::NULL_NODE)
- {
- parent_successor=successor;
- successor = T::node(mPool[successor]).left();
- }
-
- int successor_right = T::node(mPool[successor]).right();
- link_left(successor,T::node(mPool[at]).left());
- bool red=T::node(mPool[successor]).red();
- T::node(mPool[successor]).set_red(T::node(mPool[at]).red());
- T::node(mPool[at]).set_red(red);
- if (parent_successor!=-1)
- {
- link_right(successor,T::node(mPool[at]).right());
- link_left(parent_successor,at);
- }
- else
- {
- link_right(successor,at);
- }
- if (at_parent!=tree_node::NULL_NODE)
- {
- if (T::node(mPool[at_parent]).left()==at)
- {
- //my parents left child
- link_left(at_parent,successor);
- }
- else
- {
- assert(T::node(mPool[at_parent]).right()==at); // better be my parents right child then
- link_right(at_parent,successor);
- }
- }
- link_left(at,tree_node::NULL_NODE);
- link_right(at,successor_right);
- at=successor;
- int a=T::node(mPool[at]).right();
- bool r=erase_internal(key, a);
- link_right(at,a); // T::node(mPool[at]).set_right(a);
- // And Keep Going
- //----------------
- if (!r) // If It Was Not Red, We Need To Rebalance
- {
- return rebalance(at, false);
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // HELPER: Change the color of a node and children
- ////////////////////////////////////////////////////////////////////////////////////
- void set_colors(tree_node& at, bool red, bool childRed)
- {
- at.set_red(red);
- if (at.left()!=tree_node::NULL_NODE)
- {
- T::node(mPool[at.left()]).set_red(childRed);
- }
- if (at.right()!=tree_node::NULL_NODE)
- {
- T::node(mPool[at.right()]).set_red(childRed);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // HELPER: Rotate node located at (at) either left or right
- ////////////////////////////////////////////////////////////////////////////////////
- void rotate(int& at, bool left)
- {
- int t;
- if (left)
- {
- assert(T::node(mPool[at]).right()!=tree_node::NULL_NODE);
- t = T::node(mPool[at]).right();
- link_right(at,T::node(mPool[t]).left()); // T::node(mPool[at]).set_right(T::node(mPool[t]).left());
- link_left(t,at); // T::node(mPool[t]).set_left(at);
- at = t;
- }
- else
- {
- assert(T::node(mPool[at]).left()!=tree_node::NULL_NODE);
- t = T::node(mPool[at]).left();
- link_left(at,T::node(mPool[t]).right()); // T::node(mPool[at]).set_left(T::node(mPool[t]).right());
- link_right(t,at); //T::node(mPool[t]).set_right(at);
- at = t;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // HELPER: Localally rebalance the tree here
- ////////////////////////////////////////////////////////////////////////////////////
- bool rebalance(int& at, bool left)
- {
- // Decide Which Child, Left Or Right?
- //------------------------------------
- int w = (left)?(T::node(mPool[at]).right()):(T::node(mPool[at]).left()); // w is the child of at
- if (w==tree_node::NULL_NODE)
- {
- bool atWasRed = T::node(mPool[at]).red(); // Remember what mPool[at] WAS
- T::node(mPool[at]).set_red(false); // Mark mPool[at] as BLACK
- return atWasRed; // Return what it used to be
- }
- // Get A Reference To The Child W, And Record It's Children x And y
- //------------------------------------------------------------------
- tree_node& wAt = T::node(mPool[w]);
- int x = (left)?(wAt.left()):(wAt.right());// x and y are the grand children of at
- int y = (left)?(wAt.right()):(wAt.left());
- // Is The Child Black?
- //---------------------
- if (!wAt.red())
- {
- // If Both X and Y are Empty, Or Both Are Red
- //--------------------------------------------
- if ((x==tree_node::NULL_NODE || !T::node(mPool[x]).red()) &&
- (y==tree_node::NULL_NODE || !T::node(mPool[y]).red()))
- {
- bool atWasRed = T::node(mPool[at]).red(); // Remember what mPool[at] WAS
- T::node(mPool[at]).set_red(false); // Mark mPool[at] as BLACK
- wAt.set_red(true); // Mark The Child As RED
- return atWasRed; // Return what it used to be
- }
- // If Y Is Valid
- //---------------
- if (y!=tree_node::NULL_NODE && T::node(mPool[y]).red())
- {
- wAt.set_red(T::node(mPool[at]).red());
- rotate(at, left);
- T::node(mPool[T::node(mPool[at]).left()]).set_red(false);
- T::node(mPool[T::node(mPool[at]).right()]).set_red(false);
- return true;
- }
- // X Must Be Valid
- //-----------------
- T::node(mPool[x]).set_red(T::node(mPool[at]).red());
- T::node(mPool[at]).set_red(false);
- if (left)
- {
- int r=T::node(mPool[at]).right();
- rotate(r,false);
- link_right(at,r); // T::node(mPool[at]).set_right(r);
- }
- else
- {
- int r=T::node(mPool[at]).left();
- rotate(r,true);
- link_left(at,r); // T::node(mPool[at]).set_left(r);
- }
- rotate(at, left);
- return true;
- }
- // The Child Must Have Been Red
- //------------------------------
- wAt.set_red(T::node(mPool[at]).red()); // Switch Child Color
- T::node(mPool[at]).set_red(true);
- rotate(at, left); // Rotate At
- // Select The Next Rebalance Child And Recurse
- //----------------------------------------------
- if (left)
- {
- int r=T::node(mPool[at]).left();
- rebalance(r,true);
- link_left(at,r); // T::node(mPool[at]).set_left(r);
- }
- else
- {
- int r=T::node(mPool[at]).right();
- rebalance(r,false);
- link_right(at,r); //T::node(mPool[at]).set_right(r);
- }
- return true;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive front function - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int front(int at) const
- {
- if (at!=tree_node::NULL_NODE &&
- T::node(mPool[at]).left()!=tree_node::NULL_NODE)
- {
- return front(T::node(mPool[at]).left());
- }
- return at;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive back function - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int back(int at) const
- {
- if (at!=tree_node::NULL_NODE && T::node(mPool[at]).right()!=tree_node::NULL_NODE)
- {
- return back(T::node(mPool[at]).right());
- }
- return at;
- }
- protected:
- int front() const
- {
- return front(mRoot);
- }
- int back() const
- {
- return back(mRoot);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive next function - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int next(int at) const
- {
- assert(at!=tree_node::NULL_NODE);
- const TTValue& kAt = mPool[at];
- const tree_node& nAt = T::node(kAt);
- if (nAt.right()!=tree_node::NULL_NODE)
- {
- return front(nAt.right());
- }
- int child = at;
- int parent = tree_node::NULL_NODE;
- find_internal(kAt, at, mRoot, parent);
- while(parent!=tree_node::NULL_NODE && (child==T::node(mPool[parent]).right()))
- {
- child = parent;
- find_internal(mPool[parent], parent, mRoot, parent);
- }
- return parent;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // This is the map internal recursive previous function - do not use externally
- ////////////////////////////////////////////////////////////////////////////////////
- int previous(int at) const
- {
- assert(at!=tree_node::NULL_NODE);
- const TTValue& kAt = mPool[at];
- const tree_node& nAt = T::node(mPool[at]);
- if (kAt.left()!=tree_node::NULL_NODE)
- {
- return back(kAt.left());
- }
- int child = at;
- int parent = tree_node::NULL_NODE;
- find_internal(nAt, at, mRoot, parent);
- while(parent!=tree_node::NULL_NODE && (child==T::node(mPool[parent]).left()))
- {
- child = parent;
- find_internal(mPool[parent], parent, mRoot, parent);
- }
- return parent;
- }
- public:
- ////////////////////////////////////////////////////////////////////////////////////
- // Constructor
- ////////////////////////////////////////////////////////////////////////////////////
- tree_base() : mRoot(tree_node::NULL_NODE), mLastAdd(-1)
- {
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // How Many Objects Are In This Map
- ////////////////////////////////////////////////////////////////////////////////////
- int size() const
- {
- return (mPool.size());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Are There Any Objects In This Map?
- ////////////////////////////////////////////////////////////////////////////////////
- bool empty() const
- {
- return (mPool.empty());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Is This Map Filled?
- ////////////////////////////////////////////////////////////////////////////////////
- bool full() const
- {
- return (mPool.full());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Clear All Data From The Map
- ////////////////////////////////////////////////////////////////////////////////////
- void clear()
- {
- mRoot = tree_node::NULL_NODE;
- mPool.clear();
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Adds Element Value At Location Key - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- void alloc_key(const TTValue &key)
- {
-
- //fixme handle duplicates more sensibly?
- assert(!full());
- mLastAdd = mPool.alloc(key); // Grab A New One
- T::node(mPool[mLastAdd]).init(); // Initialize Our Data And Color
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Allocs an item, when filled, call insert_alloced
- ////////////////////////////////////////////////////////////////////////////////////
- TTValue & alloc_key()
- {
- assert(!full());
- mLastAdd = mPool.alloc(); // Grab A New One
- T::node(mPool[mLastAdd]).init(); // Initialize Our Data And Color
- return mPool[mLastAdd];
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Allocs an item (raw), when constucted, call insert_alloced
- ////////////////////////////////////////////////////////////////////////////////////
- TRatlNew *alloc_key_raw()
- {
- assert(!full());
- TRatlNew *ret=mPool.alloc_raw(); // Grab A New One
- mLastAdd = mPool.pointer_to_index(ret);
- T::node(mPool[mLastAdd]).init(); // Initialize Our Data And Color
- return ret;
- }
- template<class CAST_TO>
- CAST_TO *verify_alloc_key(CAST_TO *p) const
- {
- return mPool.verify_alloc(p);
- }
- void insert_alloced_key()
- {
- assert(mLastAdd>=0&&mLastAdd<CAPACITY);
- assert(!IS_MULTI || find_index(mPool[mLastAdd])!=tree_node::NULL_NODE); //fixme handle duplicates more sensibly?
- insert_internal(mPool[mLastAdd],mRoot);
- assert(mRoot!=tree_node::NULL_NODE);
- T::node(mPool[mRoot]).set_red(false);
- T::node(mPool[mRoot]).set_parent(tree_node::NULL_NODE);
- }
- int index_of_alloced_key() const
- {
- assert(mLastAdd>=0&&mLastAdd<CAPACITY);
- return mLastAdd;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Removes The Element Pointed To At (it) And Decrements (it) - O((log n)^2)
- ////////////////////////////////////////////////////////////////////////////////////
- void erase_index(int i)
- {
- assert(i>=0&&i<CAPACITY);
- assert(mRoot!=tree_node::NULL_NODE);
- //fixme this is lame to have to look by key to erase
- erase_internal(mPool[i],mRoot);
- if (mRoot!=tree_node::NULL_NODE)
- {
- T::node(mPool[mRoot]).set_red(false);
- T::node(mPool[mRoot]).set_parent(tree_node::NULL_NODE);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Seach For A Given Key. Will Return -1 if Failed - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- int find_index(const TTValue &key) const
- {
- return find_internal(key, mRoot);
- }
- const TTValue &index_to_key(int i) const
- {
- assert(i>=0&&i<CAPACITY);
- return mPool[i];
- }
- //fixme lower bound, upper bound, equal range
- };
- template<class T,int IS_MULTI>
- class set_base : public tree_base<T,IS_MULTI>
- {
- public:
- typedef typename T TStorageTraits;
- typedef typename T::TValue TTValue;
- ////////////////////////////////////////////////////////////////////////////////////
- // Capacity Enum
- ////////////////////////////////////////////////////////////////////////////////////
- enum
- {
- CAPACITY = T::CAPACITY
- };
- ////////////////////////////////////////////////////////////////////////////////////
- // Adds Element Value At Location Key - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- void insert(const TTValue &key)
- {
-
- assert(!IS_MULTI || find_index(key)==tree_node::NULL_NODE); //fixme handle duplicates more sensibly?
- alloc_key(key);
- insert_alloced_key();
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Allocs an item, when filled, call insert_alloced
- ////////////////////////////////////////////////////////////////////////////////////
- TTValue & alloc()
- {
- return alloc_key();
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Allocs an item (raw), when constucted, call insert_alloced
- ////////////////////////////////////////////////////////////////////////////////////
- TRatlNew *alloc_raw()
- {
- return alloc_key_raw();
- }
- template<class CAST_TO>
- CAST_TO *verify_alloc(CAST_TO *p) const
- {
- return verify_alloc_key(p);
- }
- void insert_alloced()
- {
- insert_alloced_key();
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Removes The First Element With Key (key) - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- void erase(const TTValue &key)
- {
- //fixme this is a double search currently
- int i=find_index(key);
- if (i!=tree_node::NULL_NODE)
- {
- erase_index(i);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Iterator
- //
- // A map is sorted in ascending order on the KEY type. ++ and -- are both
- // O((log n)^2) operations
- //
- ////////////////////////////////////////////////////////////////////////////////////
- class iterator
- {
- friend class set_base<TStorageTraits,IS_MULTI>;
- friend class const_iterator;
- int mLoc;
- set_base<TStorageTraits,IS_MULTI>* mOwner;
- public:
- iterator(set_base<TStorageTraits,IS_MULTI> *owner=0, int loc=tree_node::NULL_NODE) :
- mOwner(owner),
- mLoc(loc)
- {
- }
- iterator(const iterator &o) :
- mOwner(o.mOwner),
- mLoc(o.mLoc)
- {
- }
- void operator=(const iterator &o)
- {
- mOwner=o.mOwner;
- mLoc=o.mLoc;
- }
- iterator operator++() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->next(mLoc);
- return *this;
- }
- iterator operator++(int) //postfix
- {
- assert(mOwner);
- iterator old(*this);
- mLoc=mOwner->next(mLoc);
- return old;
- }
- iterator operator--() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->previous(mLoc);
- return *this;
- }
- iterator operator--(int) //postfix
- {
- assert(mOwner);
- iterator old(*this);
- mLoc=mOwner->previous(mLoc);
- return old;
- }
- bool operator!=(const iterator p) const {return (mLoc!=p.mLoc || mOwner!=p.mOwner);}
- bool operator==(const iterator p) const {return (mLoc==p.mLoc && mOwner==p.mOwner);}
- const TTValue & operator*() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->index_to_key(mLoc);
- }
- const TTValue * operator->() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return &mOwner->index_to_key(mLoc);
- }
- };
- class const_iterator
- {
- friend class set_base<TStorageTraits,IS_MULTI>;
- int mLoc;
- const set_base<TStorageTraits,IS_MULTI>* mOwner;
- public:
- const_iterator(const set_base<TStorageTraits,IS_MULTI> *owner=0, int loc=tree_node::NULL_NODE) :
- mOwner(owner),
- mLoc(loc)
- {
- }
- const_iterator(const const_iterator &o) :
- mOwner(o.mOwner),
- mLoc(o.mLoc)
- {
- }
- const_iterator(const iterator &o) :
- mOwner(o.mOwner),
- mLoc(o.mLoc)
- {
- }
- void operator=(const const_iterator &o)
- {
- mOwner=o.mOwner;
- mLoc=o.mLoc;
- }
- void operator=(const iterator &o)
- {
- mOwner=o.mOwner;
- mLoc=o.mLoc;
- }
- const_iterator operator++() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->next(mLoc);
- return *this;
- }
- const_iterator operator++(int) //postfix
- {
- assert(mOwner);
- const_iterator old(*this);
- mLoc=mOwner->next(mLoc);
- return old;
- }
- const_iterator operator--() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->previous(mLoc);
- return *this;
- }
- const_iterator operator--(int) //postfix
- {
- assert(mOwner);
- const_iterator old(*this);
- mLoc=mOwner->previous(mLoc);
- return old;
- }
- bool operator!=(const const_iterator p) const {return (mLoc!=p.mLoc || mOwner!=p.mOwner);}
- bool operator==(const const_iterator p) const {return (mLoc==p.mLoc && mOwner==p.mOwner);}
- bool operator!=(const iterator p) const {return (mLoc!=p.mLoc || mOwner!=p.mOwner);}
- bool operator==(const iterator p) const {return (mLoc==p.mLoc && mOwner==p.mOwner);}
- const TTValue & operator*() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->index_to_key(mLoc);
- }
- const TTValue * operator->() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return &mOwner->index_to_key(mLoc);
- }
- };
- friend class iterator;
- friend class const_iterator;
- ////////////////////////////////////////////////////////////////////////////////////
- // Seach For A Given Key. Will Return end() if Failed - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator find(const TTValue &key)
- {
- return iterator(this,find_index(key));
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An Iterator To The Smallest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator begin()
- {
- return iterator(this, front());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An Iterator To The Largest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator rbegin()
- {
- return iterator(this, back());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // The Invalid Iterator, Use As A Stop Condition In Your For Loops - O(1)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator end()
- {
- return iterator(this);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Seach For A Given Key. Will Return end() if Failed - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator find(const TTValue &key) const
- {
- return const_iterator(this, find_index(key));
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An const_iterator To The Smallest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator begin() const
- {
- return const_iterator(this, front());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An const_iterator To The Largest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator rbegin() const
- {
- return const_iterator(this, back());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // The Invalid const_iterator, Use As A Stop Condition In Your For Loops - O(1)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator end() const
- {
- return const_iterator(this);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Removes The Element Pointed To At (it) And Decrements (it) - O((log n)^2)
- ////////////////////////////////////////////////////////////////////////////////////
- void erase(const iterator &it)
- {
- assert(it.mOwner==this && it.mLoc>=0&&it.mLoc<CAPACITY);
- erase_index(it.mLoc);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- //
- ////////////////////////////////////////////////////////////////////////////////////
- iterator lower_bound(const TTValue &key)
- {
- return iterator(this, find_index(key));
- }
- ////////////////////////////////////////////////////////////////////////////////////
- //
- ////////////////////////////////////////////////////////////////////////////////////
- iterator upper_bound(const TTValue &key)
- {
- // fixme, this don't work
- iterator ubound(this, find_index(key));
- ubound++;
- return ubound;
- }
- };
- template<class T, int ARG_CAPACITY>
- class set_vs : public set_base<storage::value_semantics_node<T,ARG_CAPACITY,tree_node>,0 >
- {
- public:
- typedef typename storage::value_semantics_node<T,ARG_CAPACITY,tree_node> TStorageTraits;
- typedef typename TStorageTraits::TValue TTValue;
- enum
- {
- CAPACITY = ARG_CAPACITY
- };
- set_vs() {}
- };
- template<class T, int ARG_CAPACITY>
- class set_os : public set_base<storage::object_semantics_node<T,ARG_CAPACITY,tree_node>,0 >
- {
- public:
- typedef typename storage::object_semantics_node<T,ARG_CAPACITY,tree_node> TStorageTraits;
- typedef typename TStorageTraits::TValue TTValue;
- enum
- {
- CAPACITY = ARG_CAPACITY
- };
- set_os() {}
- };
- template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
- class set_is : public set_base<storage::virtual_semantics_node<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE,tree_node>,0 >
- {
- public:
- typedef typename storage::virtual_semantics_node<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE,tree_node> TStorageTraits;
- typedef typename TStorageTraits::TValue TTValue;
- enum
- {
- CAPACITY = ARG_CAPACITY,
- MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
- };
- set_is() {}
- };
- template<class K,class V,int IS_MULTI>
- class map_base : public tree_base<K,IS_MULTI>
- {
- public:
- typedef typename K TKeyStorageTraits;
- typedef typename K::TValue TKTValue;
- typedef typename V TValueStorageTraits;
- typedef typename V::TValue TVTValue;
- ////////////////////////////////////////////////////////////////////////////////////
- // Capacity Enum
- ////////////////////////////////////////////////////////////////////////////////////
- enum
- {
- CAPACITY = K::CAPACITY
- };
- private:
- array_base<TValueStorageTraits> mValues;
- public:
- map_base()
- {
- compile_assert<K::CAPACITY==V::CAPACITY>();
- }
- void clear()
- {
- tree_base<K,IS_MULTI>::clear();
- mValues.clear();
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Adds Element Value At Location Key - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- void insert(const TKTValue &key,const TVTValue &value)
- {
- assert(!IS_MULTI || find_index(key)==tree_node::NULL_NODE); //fixme handle duplicates more sensibly?
- alloc_key(key);
- insert_alloced_key();
- assert(check_validity());
- mValues.construct(index_of_alloced_key(),value);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Adds Element Value At Location Key returns a reference
- ////////////////////////////////////////////////////////////////////////////////////
- TVTValue &insert(const TKTValue &key)
- {
-
- assert(!IS_MULTI || find_index(key)==tree_node::NULL_NODE); //fixme handle duplicates more sensibly?
- alloc_key(key);
- insert_alloced_key();
- int idx=index_of_alloced_key();
- assert(check_validity());
- mValues.construct(idx);
- return mValues[idx];
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Adds Element Value At Location Key returns a rew pointer for placement new
- ////////////////////////////////////////////////////////////////////////////////////
- TRatlNew *insert_raw(const TKTValue &key)
- {
-
- assert(!IS_MULTI || find_index(key)==tree_node::NULL_NODE); //fixme handle duplicates more sensibly?
- alloc_key(key);
- insert_alloced_key();
- assert(check_validity());
- return mValues.alloc_raw(index_of_alloced_key());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // After calling alloc_key*, you may call this to alloc the value
- ////////////////////////////////////////////////////////////////////////////////////
- TVTValue &alloc_value()
- {
- mValues.construct(index_of_alloced_key());
- return mValues[index_of_alloced_key()];
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // After calling alloc_key*, you may call this to alloc_raw the value
- ////////////////////////////////////////////////////////////////////////////////////
- TRatlNew *alloc_value_raw()
- {
- return mValues.alloc_raw(index_of_alloced_key());
- }
- template<class CAST_TO>
- CAST_TO *verify_alloc(CAST_TO *p) const
- {
- return mValues.verify_alloc(p);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Removes The First Element With Key (key) - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- void erase(const TKTValue &key)
- {
- //fixme this is a double search currently
- int i=find_index(key);
- if (i!=tree_node::NULL_NODE)
- {
- erase_index(i);
- mValues.destruct(i);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Iterator
- //
- // A map is sorted in ascending order on the KEY type. ++ and -- are both
- // O((log n)^2) operations
- //
- ////////////////////////////////////////////////////////////////////////////////////
- class const_iterator;
- class iterator
- {
- friend class map_base<K,V, IS_MULTI>;
- friend class const_iterator;
- int mLoc;
- map_base<K,V, IS_MULTI>* mOwner;
- public:
- iterator(map_base<K,V, IS_MULTI> *owner=0, int loc=tree_node::NULL_NODE) :
- mOwner(owner),
- mLoc(loc)
- {
- }
- iterator(const iterator &o) :
- mOwner(o.mOwner),
- mLoc(o.mLoc)
- {
- }
- void operator=(const iterator &o)
- {
- mOwner=o.mOwner;
- mLoc=o.mLoc;
- }
- iterator operator++() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->next(mLoc);
- return *this;
- }
- iterator operator++(int) //postfix
- {
- assert(mOwner);
- iterator old(*this);
- mLoc=mOwner->next(mLoc);
- return old;
- }
- iterator operator--() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->previous(mLoc);
- return *this;
- }
- iterator operator--(int) //postfix
- {
- assert(mOwner);
- iterator old(*this);
- mLoc=mOwner->previous(mLoc);
- return old;
- }
- bool operator!=(const iterator &p) const {return (mLoc!=p.mLoc || mOwner!=p.mOwner);}
- bool operator==(const iterator &p) const {return (mLoc==p.mLoc && mOwner==p.mOwner);}
- TVTValue & operator*() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->mValues[mLoc];
- }
- const TKTValue & key() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->index_to_key(mLoc);
- }
- TVTValue & value() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->mValues[mLoc];
- }
- TVTValue * operator->() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return &mOwner->mValues[mLoc];
- }
- };
- class const_iterator
- {
- friend class map_base<K,V,IS_MULTI>;
- int mLoc;
- const map_base<K,V,IS_MULTI>* mOwner;
- public:
- const_iterator(const map_base<K,V,IS_MULTI> *owner=0, int loc=tree_node::NULL_NODE) :
- mOwner(owner),
- mLoc(loc)
- {
- }
- const_iterator(const const_iterator &o) :
- mOwner(o.mOwner),
- mLoc(o.mLoc)
- {
- }
- const_iterator(const iterator &o) :
- mOwner(o.mOwner),
- mLoc(o.mLoc)
- {
- }
- void operator=(const const_iterator &o)
- {
- mOwner=o.mOwner;
- mLoc=o.mLoc;
- }
- void operator=(const iterator &o)
- {
- mOwner=o.mOwner;
- mLoc=o.mLoc;
- }
- const_iterator operator++() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->next(mLoc);
- return *this;
- }
- const_iterator operator++(int) //postfix
- {
- assert(mOwner);
- const_iterator old(*this);
- mLoc=mOwner->next(mLoc);
- return old;
- }
- const_iterator operator--() //prefix
- {
- assert(mOwner);
- mLoc=mOwner->previous(mLoc);
- return *this;
- }
- const_iterator operator--(int) //postfix
- {
- assert(mOwner);
- const_iterator old(*this);
- mLoc=mOwner->previous(mLoc);
- return old;
- }
- bool operator!=(const const_iterator &p) const {return (mLoc!=p.mLoc || mOwner!=p.mOwner);}
- bool operator==(const const_iterator &p) const {return (mLoc==p.mLoc && mOwner==p.mOwner);}
- bool operator!=(const iterator &p) const {return (mLoc!=p.mLoc || mOwner!=p.mOwner);}
- bool operator==(const iterator &p) const {return (mLoc==p.mLoc && mOwner==p.mOwner);}
- const TVTValue & operator*() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->mValues[mLoc];
- }
- const TKTValue & key() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->index_to_key(mLoc);
- }
- const TVTValue & value() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return mOwner->mValues[mLoc];
- }
- const TVTValue * operator->() const
- {
- assert(mOwner);
- assert(mLoc>=0&&mLoc<CAPACITY); // deferencing end()?
- return &mOwner->mValues[mLoc];
- }
- };
- friend class iterator;
- friend class const_iterator;
- ////////////////////////////////////////////////////////////////////////////////////
- // Seach For A Given Key. Will Return end() if Failed - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator find(const TKTValue &key)
- {
- return iterator(this,find_index(key));
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An Iterator To The Smallest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator begin()
- {
- return iterator(this, front());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An Iterator To The Largest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator rbegin()
- {
- return iterator(this, back());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // The Invalid Iterator, Use As A Stop Condition In Your For Loops - O(1)
- ////////////////////////////////////////////////////////////////////////////////////
- iterator end()
- {
- return iterator(this);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Seach For A Given Key. Will Return end() if Failed - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator find(const TKTValue &key) const
- {
- return const_iterator(this, find_index(key));
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An const_iterator To The Smallest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator begin() const
- {
- return const_iterator(this, front());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Get An const_iterator To The Largest Element - O(log n)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator rbegin() const
- {
- return const_iterator(this, back());
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // The Invalid const_iterator, Use As A Stop Condition In Your For Loops - O(1)
- ////////////////////////////////////////////////////////////////////////////////////
- const_iterator end() const
- {
- return const_iterator(this);
- }
- ////////////////////////////////////////////////////////////////////////////////////
- // Removes The Element Pointed To At (it) And Decrements (it) - O((log n)^2)
- ////////////////////////////////////////////////////////////////////////////////////
- void erase(const iterator &it)
- {
- assert(it.mOwner==this && it.mLoc>=0&&it.mLoc<CAPACITY);
- erase_index(it.mLoc);
- mValues.destruct(it.mLoc);
- }
- private:
- bool check_validity()
- {
- #if (0)
- int cnt=0;
- iterator it=begin();
- for (;it!=end();it++)
- {
- cnt++;
- }
- // assert(cnt==size());
- return cnt==size();
- #else
- return true;
- #endif
- }
- };
- template<class K,class V, int ARG_CAPACITY>
- class map_vs : public map_base<
- storage::value_semantics_node<K,ARG_CAPACITY,tree_node>,
- storage::value_semantics<V,ARG_CAPACITY>,
- 0 >
- {
- public:
- typedef typename storage::value_semantics<V,ARG_CAPACITY> VStorageTraits;
- typedef typename VStorageTraits::TValue TTValue;
- enum
- {
- CAPACITY = ARG_CAPACITY
- };
- map_vs() {}
- };
- template<class K,class V, int ARG_CAPACITY>
- class map_os : public map_base<
- storage::value_semantics_node<K,ARG_CAPACITY,tree_node>,
- storage::object_semantics<V,ARG_CAPACITY>,
- 0 >
- {
- public:
- typedef typename storage::object_semantics<V,ARG_CAPACITY> VStorageTraits;
- typedef typename VStorageTraits::TValue TTValue;
- enum
- {
- CAPACITY = ARG_CAPACITY
- };
- map_os() {}
- };
- template<class K,class V, int ARG_CAPACITY,int ARG_MAX_CLASS_SIZE>
- class map_is : public map_base<
- storage::value_semantics_node<K,ARG_CAPACITY,tree_node>,
- storage::virtual_semantics<V,ARG_CAPACITY,ARG_MAX_CLASS_SIZE>,
- 0 >
- {
- public:
- typedef typename storage::virtual_semantics<V,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> VStorageTraits;
- typedef typename VStorageTraits::TValue TTValue;
- enum
- {
- CAPACITY = ARG_CAPACITY,
- MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
- };
- map_is() {}
- };
- }
- #endif
|