diff --git a/src/libCom/cxxTemplates/resourceLib.h b/src/libCom/cxxTemplates/resourceLib.h index b2a647d00..f9846906f 100644 --- a/src/libCom/cxxTemplates/resourceLib.h +++ b/src/libCom/cxxTemplates/resourceLib.h @@ -387,16 +387,12 @@ void resTable::destroyAllEntries() tsSLList *pList = this->pTable; while (pList<&this->pTable[this->hashIdMask+1]) { - T *pItem; - T *pNextItem; - { - tsSLIter iter(*pList); - pItem = iter(); - while (pItem) { - pNextItem = iter(); - pItem->destroy(); - pItem = pNextItem; + tsSLIter iter ( pList->first () ); + while ( iter.valid () ) { + tsSLIter iterTmp = iter.itemAfter (); + iter->destroy(); + iter = iterTmp; } } @@ -406,15 +402,14 @@ void resTable::destroyAllEntries() // from the resTable when it is destroyed. // { - tsSLIterRm iter(*pList); - while ( (pItem=iter()) ) { - fprintf (stderr, -"Warning: Defective class still in resTable after it was destroyed\n"); + T *pItem; + while ( ( pItem = pList.get () ) ) { + fprintf ( stderr, +"Warning: Defective class still in resTable after it was destroyed\n" ); // // remove defective class // - iter.remove(); - this->nInUse--; + this->nInUse--; } } @@ -437,27 +432,27 @@ void resTable::show (unsigned level) const printf("resTable with %d resources installed\n", this->nInUse); - if (level >=1u) { + if ( level >=1u ) { pList = this->pTable; X = 0.0; XX = 0.0; maxEntries = 0u; - while (pList < &this->pTable[this->hashIdMask+1]) { + while ( pList < &this->pTable[this->hashIdMask+1] ) { unsigned count; - tsSLIter iter(*pList); - T *pItem; + tsSLIter pItem ( pList->first () ); count = 0; - while ( (pItem = iter()) ) { - if (level >= 3u) { + while ( pItem.valid () ) { + if ( level >= 3u ) { pItem->show (level); } count++; + pItem = pItem->itemAfter (); } - if (count>0u) { + if ( count > 0u ) { X += count; - XX += count*count; - if (count>maxEntries) { + XX += count * count; + if ( count > maxEntries ) { maxEntries = count; } } @@ -481,12 +476,12 @@ void resTable::traverse (pSetMFArg(pCB)) const tsSLList *pList; pList = this->pTable; - while (pList < &this->pTable[this->hashIdMask+1]) { - tsSLIter iter(*pList); - T *pItem; + while ( pList < &this->pTable[this->hashIdMask+1] ) { + tsSLIter pItem ( pList->first () ); - while ( (pItem = iter()) ) { + while ( pItem.valid () ) { (pItem->*pCB) (); + pItem = pItem->itemAfter (); } pList++; } @@ -526,15 +521,15 @@ int resTable::add (T &res) template T *resTable::find (tsSLList &list, const ID &idIn) const { - tsSLIter iter(list); - T *pItem; + tsSLIter pItem ( list.first () ); ID *pId; - while ( (pItem = iter()) ) { - pId = pItem; - if (*pId == idIn) { + while ( pItem.valid () ) { + pId = & (*pItem) ; + if ( *pId == idIn ) { break; } + pItem = pItem->itemAfter (); } return pItem; } @@ -552,19 +547,26 @@ T *resTable::find (tsSLList &list, const ID &idIn) const template T *resTable::findDelete (tsSLList &list, const ID &idIn) { - tsSLIterRm iter(list); - T *pItem; + tsSLIter pItem ( list.first () ); + tsSLIter pPrev ( 0 ); ID *pId; - while ( (pItem = iter()) ) { - pId = pItem; - if (*pId == idIn) { - iter.remove(); + while ( pItem.valid () ) { + pId = & (*pItem); + if ( *pId == idIn ) { + if ( pPrev.valid () ) { + list.remove ( *pPrev ); + } + else { + list.get (); + } this->nInUse--; break; } + pPrev = pItem; + pItem = pItem->itemAfter (); } - return pItem; + return & (*pItem); } // @@ -599,15 +601,15 @@ inline resTableIter::resTableIter (const resTable &tableIn) : template inline T * resTableIter::next () { - T *pNext = this->iter.next(); - if (pNext) { - return pNext; + this->iter = this->iter.itemAfter (); + if ( this->iter.valid () ) { + return & ( *this->iter ); } if ( this->index >= (1u<table.hashIdNBits) ) { return 0; } - this->iter = tsSLIter (this->table.pTable[this->index++]); - return this->iter.next (); + this->iter = tsSLIter ( this->table.pTable[this->index++].first () ); + return & ( *this->iter ); } // diff --git a/src/libCom/cxxTemplates/test/tsSLListBench.cc b/src/libCom/cxxTemplates/test/tsSLListBench.cc index f4cc965b7..7d9cfb566 100644 --- a/src/libCom/cxxTemplates/test/tsSLListBench.cc +++ b/src/libCom/cxxTemplates/test/tsSLListBench.cc @@ -45,9 +45,10 @@ int main () clk = clock(); { - tsSLIter iter(list); - while ( (pFred = iter()) ) { - pFred->inc(); + tsSLIter iter ( list.first () ); + while ( iter.valid () ) { + iter->inc (); + iter++; } } diff = clock() - clk; @@ -59,9 +60,9 @@ int main () pFred = new fred(); clk = clock(); { - tsSLIter iter(list); - for (i=0; iinc(); + tsSLIter iter ( list.first () ); + for ( i=0; iinc(); } } diff = clock() - clk; diff --git a/src/libCom/cxxTemplates/test/tsSLListTest.cc b/src/libCom/cxxTemplates/test/tsSLListTest.cc index ef65d3f51..f9822ff80 100644 --- a/src/libCom/cxxTemplates/test/tsSLListTest.cc +++ b/src/libCom/cxxTemplates/test/tsSLListTest.cc @@ -34,26 +34,22 @@ int main () list.add(*pFred); list.add(*pFredII); { - tsSLIterRm iter(list); - pFredBack = iter(); - assert(pFredBack == pFredII); - pFredBack = iter(); - assert(pFredBack == pFred); - iter.remove(); // removes pFred + tsSLIter iter1( pFredII ); + tsSLIter iter2( list.first () ); + tsSLIter iter3( pFred ); + assert ( iter1 == iter2 ); + iter2++; + assert ( iter3 == iter2 ); + list.remove ( *pFredII ); // removes pFred } - list.add(*pFred); + list.add ( *pFred ); pFredBack = list.get(); assert (pFredBack == pFred); pFredBack = list.get(); assert (pFredBack == pFredII); list.add(*pFredII); list.add(*pFred); - { - tsSLIterRm iter(list); - while ( (pFredBack = iter()) ) { - iter.remove(); - } - } + while ( list.get () ); pFredBack = list.get(); assert (pFredBack == 0); list.add(*pFred); @@ -62,9 +58,10 @@ int main () list.add(* new fred("D")); { - tsSLIter iter(list); - while ( (pFredBack = iter()) ) { - pFredBack->show(); + tsSLIter iter ( list.first() ); + while ( iter.valid () ) { + iter->show(); + ++iter; } } @@ -74,30 +71,26 @@ int main () janeList.add(*pJane); { - tsSLIter janeIter(janeList); - while ( (pJane = janeIter()) ) { - pJane->show(); + tsSLIter iter ( janeList.first() ); + while ( iter.valid () ) { + iter->show(); + ++iter; } } { - tsSLIter iter(list); - while ( (pFredBack = iter()) ) { - pFredBack->show(); + tsSLIter iter ( list.first () ); + while ( iter.valid () ) { + iter->show(); + iter++; } } - { - tsSLIterRm iter(list); - while ( (pFredBack = iter()) ) { - iter.remove(); - } - } + while ( list.get () ); { - tsSLIter iter(list); - pFredBack = iter(); - assert(pFredBack==NULL); + tsSLIter iter (list.first()); + assert ( iter == tsSLIter::eol() ); } return 0; diff --git a/src/libCom/cxxTemplates/tsSLList.h b/src/libCom/cxxTemplates/tsSLList.h index c2ba7531c..43ed31911 100644 --- a/src/libCom/cxxTemplates/tsSLList.h +++ b/src/libCom/cxxTemplates/tsSLList.h @@ -44,9 +44,9 @@ // the hp compiler complains about parameterized friend // class that has not been declared without this? // -template class tsSLList; -template class tsSLIter; -template class tsSLIterRm; +template < class T > class tsSLList; +template < class T > class tsSLIter; +template < class T > class tsSLIterRm; // // tsSLNode @@ -54,15 +54,15 @@ template class tsSLIterRm; // template class tsSLNode { -friend class tsSLList; -friend class tsSLIter; -friend class tsSLIterRm; +friend class tsSLList < T >; +friend class tsSLIter < T >; +friend class tsSLIterRm < T >; public: tsSLNode (); - void operator = (const tsSLNode &) const; + void operator = ( const tsSLNode < T > & ) const; private: void removeNextItem (); // removes the item after this node - T *pNext; + T *pNext; }; @@ -70,52 +70,91 @@ private: // tsSLList // NOTE: class T must derive from tsSLNode // -template -class tsSLList : public tsSLNode { +template < class T > +class tsSLList : public tsSLNode < T > { public: tsSLList (); // creates an empty list - void insert (T &item, tsSLNode &itemBefore); // insert after item before - void add (T &item); // add to the beginning of the list + void insert ( T &item, tsSLNode < T > &itemBefore ); // insert after item before + void add ( T &item ); // add to the beginning of the list T * get (); // remove from the beginning of the list T * pop (); // same as get - void push (T &item); // same as add + void push ( T &item ); // same as add + T * first () const; + void remove ( T &itemBefore ); private: - tsSLList (const tsSLList &); // intentionally _not_ implemented + tsSLList ( const tsSLList & ); // intentionally _not_ implemented +}; + +// +// tsSLIterConst +// +template < class T > +class tsSLIterConst { +public: + tsSLIterConst ( const T *pInitialEntry ); + + tsSLIterConst & operator = ( const T *pNewEntry ); + + tsSLIterConst itemAfter (); + + bool operator == (const tsSLIterConst &rhs) const; + bool operator != (const tsSLIterConst &rhs) const; + + const T & operator * () const; + const T * operator -> () const; + + tsSLIterConst operator ++ (); // prefix ++ + tsSLIterConst operator ++ (int); // postfix ++ + +# if defined(_MSC_VER) && _MSC_VER < 1200 + tsSLIterConst (const class tsSLIterConst ©In); +# endif + + bool valid () const; + + // + // end of the list constant + // + static const tsSLIterConst eol (); + +protected: + union { + const T *pConstEntry; + T *pEntry; + }; }; // // tsSLIter // -template -class tsSLIter { +template < class T > +class tsSLIter : private tsSLIterConst { public: - tsSLIter (const tsSLList &listIn); - T * next (); // move iterator forward - T * operator () (); // same as next () -private: - T *pCurrent; -}; + tsSLIter ( T *pInitialEntry ); -// -// tsSLIterRm -// (An tsSLIter that allows removing a node) -// -template -class tsSLIterRm { -public: + tsSLIter & operator = ( T *pNewEntry ); + + tsSLIter itemAfter (); + + bool operator == (const tsSLIter &rhs) const; + bool operator != (const tsSLIter &rhs) const; + + T & operator * () const; + T * operator -> () const; + + tsSLIter operator ++ (); // prefix ++ + tsSLIter operator ++ (int); // postfix ++ + +# if defined(_MSC_VER) && _MSC_VER < 1200 + tsSLIter (class tsSLIter ©In); +# endif + + bool valid () const; // - // exceptions + // end of the list constant // - class noCurrentItemInIterator {}; - - tsSLIterRm (tsSLList &listIn); - T * next (); // move iterator forward - T * operator () (); // same as next () - void remove (); // remove current node -private: - T *pPrevious; - T *pCurrent; + static const tsSLIter eol (); }; ////////////////////////////////////////// @@ -127,8 +166,8 @@ private: // // tsSLNode::tsSLNode // -template -tsSLNode::tsSLNode() : pNext(0) {} +template < class T > +tsSLNode < T > ::tsSLNode () : pNext ( 0 ) {} // // tsSLNode::operator = @@ -136,8 +175,8 @@ tsSLNode::tsSLNode() : pNext(0) {} // when someone copies into a class deriving from this // do _not_ change the node pointers // -template -inline void tsSLNode::operator = (const tsSLNode &) const {} +template < class T > +inline void tsSLNode < T >::operator = ( const tsSLNode < T > & ) const {} // // removeNextItem () @@ -148,8 +187,8 @@ template inline void tsSLNode::removeNextItem () { T *pItem = this->pNext; - if (pItem) { - tsSLNode *pNode = pItem; + if ( pItem ) { + tsSLNode < T > *pNode = pItem; this->pNext = pNode->pNext; } } @@ -164,8 +203,8 @@ inline void tsSLNode::removeNextItem () // tsSLList::tsSLList() // create an empty list // -template -inline tsSLList::tsSLList () +template < class T > +inline tsSLList < T > :: tsSLList () { } @@ -174,10 +213,10 @@ inline tsSLList::tsSLList () // (itemBefore might be the list header object and therefore // will not always be of type T) // -template -inline void tsSLList::insert (T &item, tsSLNode &itemBefore) +template < class T > +inline void tsSLList < T > :: insert ( T &item, tsSLNode < T > &itemBefore ) { - tsSLNode &node = item; + tsSLNode < T > &node = item; node.pNext = itemBefore.pNext; itemBefore.pNext = &item; } @@ -185,40 +224,146 @@ inline void tsSLList::insert (T &item, tsSLNode &itemBefore) // // tsSLList::add () // -template -inline void tsSLList::add (T &item) +template < class T > +inline void tsSLList < T > :: add ( T &item ) { - this->insert (item, *this); + this->insert ( item, *this ); } // // tsSLList::get () // -template -inline T * tsSLList::get() +template < class T > +inline T * tsSLList < T > :: get () { - tsSLNode *pThisNode = this; + tsSLNode < T > *pThisNode = this; T *pItem = pThisNode->pNext; - pThisNode->removeNextItem(); + pThisNode->removeNextItem (); return pItem; } // // tsSLList::pop () // -template -inline T * tsSLList::pop() +template < class T > +inline T * tsSLList < T > :: pop () { - return this->get(); + return this->get (); } // // tsSLList::push () // template -inline void tsSLList::push(T &item) +inline void tsSLList < T > :: push ( T &item ) { - this->add(item); + this->add (item); +} + +template +inline T * tsSLList < T > :: first () const +{ + tsSLNode < T > *pThisNode = this; + return pThisNode->pNext; +} + +template +void tsSLList < T > :: remove ( T &itemBefore ) +{ + tsSLNode < T > *pBeforeNode = &itemBefore; + tsSLNode < T > *pAfterNode = pBeforeNode->pNext; + pBeforeNode->pNext = pAfterNode->pNext; +} + +////////////////////////////////////////// +// +// tsSLIterConst inline member functions +// +////////////////////////////////////////// + +template < class T > +inline tsSLIterConst::tsSLIterConst ( const T *pInitialEntry ) : + pConstEntry ( pInitialEntry ) +{ +} + +template < class T > +inline tsSLIterConst & tsSLIterConst::operator = ( const T *pNewEntry ) +{ + this->pConstEntry = pNewEntry; + return *this; +} + +template < class T > +inline tsSLIterConst tsSLIterConst::itemAfter () +{ + tsSLNode < T > *pCurNode = this->pConstEntry; + return pCurNode->pNext; +} + +template < class T > +inline bool tsSLIterConst::operator == ( const tsSLIterConst &rhs ) const +{ + return this->pConstEntry == rhs.pConstEntry; +} + +template < class T > +inline bool tsSLIterConst::operator != (const tsSLIterConst &rhs) const +{ + return this->pConstEntry != rhs.pConstEntry; +} + +template < class T > +inline const T & tsSLIterConst::operator * () const +{ + return *this->pConstEntry; +} + +template < class T > +inline const T * tsSLIterConst::operator -> () const +{ + return this->pConstEntry; +} + +template < class T > +inline tsSLIterConst tsSLIterConst::operator ++ () // prefix ++ +{ + tsSLNode < T > *pCurNode = this->pConstEntry; + this->pConstEntry = pCurNode->pNext; + return *this; +} + +template < class T > +inline tsSLIterConst tsSLIterConst::operator ++ (int) // postfix ++ +{ + tsSLIterConst tmp = *this; + tsSLNode < T > *pCurNode = this->pConstEntry; + this->pConstEntry = pCurNode->pNext; + return tmp; +} + + +# if defined(_MSC_VER) && _MSC_VER < 1200 +template < class T > +inline tsSLIterConst::tsSLIterConst (const class tsSLIterConst ©In) : + pConstEntry ( copyIn.pConstEntry ) +{ +} +# endif + +template < class T > +inline bool tsSLIterConst::valid () const +{ + return this->pConstEntry ? true : false; +} + +// +// end of the list constant +// +template < class T > +inline static const tsSLIterConst tsSLIterConst::eol () +{ + return 0; } ////////////////////////////////////////// @@ -227,117 +372,88 @@ inline void tsSLList::push(T &item) // ////////////////////////////////////////// +template < class T > +inline tsSLIter::tsSLIter ( T *pInitialEntry ) : + tsSLIterConst ( pInitialEntry ) +{ +} + +template < class T > +inline tsSLIter & tsSLIter::operator = ( T *pNewEntry ) +{ + tsSLIterConst::operator = ( pNewEntry ); + return *this; +} + +template < class T > +inline tsSLIter tsSLIter::itemAfter () +{ + tsSLNode < T > *pCurNode = this->pEntry; + return pCurNode->pNext; +} + +template < class T > +inline bool tsSLIter::operator == ( const tsSLIter &rhs ) const +{ + return this->pEntry == rhs.pEntry; +} + +template < class T > +inline bool tsSLIter::operator != (const tsSLIter &rhs) const +{ + return this->pEntry != rhs.pEntry; +} + +template < class T > +inline T & tsSLIter::operator * () const +{ + return *this->pEntry; +} + +template < class T > +inline T * tsSLIter::operator -> () const +{ + return this->pEntry; +} + +template < class T > +inline tsSLIter tsSLIter::operator ++ () // prefix ++ +{ + this->tsSLIterConst::operator ++ (); + return *this; +} + +template < class T > +inline tsSLIter tsSLIter::operator ++ (int) // postfix ++ +{ + tsSLIterConst tmp = *this; + this->tsSLIterConst::operator ++ (); + return tmp; +} + + +# if defined(_MSC_VER) && _MSC_VER < 1200 +template < class T > +inline tsSLIter::tsSLIter (const class tsSLIter ©In) : + tsSLIterConst ( copyIn ) +{ +} +# endif + +template < class T > +inline bool tsSLIter::valid () const +{ + return this->pEntry ? true : false; +} + // -// tsSLIter::tsSLIter +// end of the list constant // template < class T > -inline tsSLIter < T > :: tsSLIter ( const tsSLList < T > &listIn ) : - pCurrent ( &listIn ) {} - -// -// tsSLIter::next () -// -// move iterator forward -// -template < class T > -inline T * tsSLIter < T > :: next () +inline static const tsSLIter tsSLIter::eol () { - tsSLNode < T > *pCurNode = this->pCurrent; - this->pCurrent = pCurNode->pNext; - return this->pCurrent; + return 0; } -// -// move iterator forward -// -template -inline T * tsSLIter::operator () () -{ - return this->next(); -} - -////////////////////////////////////////// -// -// tsSLIterRm inline member functions -// -// adds remove method (and does not construct -// with const list) -// -// tsSLIter isnt a base class because this -// requires striping const from pCurrent which could get -// us in trouble with a high quality -// optimizing compiler -// -// Notes: -// 1) No direct access to pCurrent is provided since -// this might allow for confusion when an item -// is removed (and pCurrent ends up pointing at -// an item that has been seen before) -// -////////////////////////////////////////// - -// -// tsSLIterRm::tsSLIterRm () -// -template -inline tsSLIterRm::tsSLIterRm ( tsSLList &listIn ) : - pPrevious ( 0 ), pCurrent ( &listIn ) {} - - -// -// tsSLIterRm::next () -// -// move iterator forward -// -// NULL test here is inefficient, but it appears that some architectures -// (intel) dont like to cast a NULL pointer from a tsSLNode to a T even if -// tsSLNode is always a base class of a T. -// -template -inline T * tsSLIterRm::next () -{ - tsSLNode *pCurNode = this->pCurrent; - this->pPrevious = this->pCurrent; - this->pCurrent = pCurNode->pNext; - return this->pCurrent; -} - -// -// move iterator forward -// -template -inline T * tsSLIterRm::operator () () -{ - return this->next(); -} - -// -// tsSLIterRm::remove () -// -// remove current node -// (and move current to be the previous item - -// the item seen by the iterator before the -// current one - this guarantee that the list -// will be accessed sequentially even if an item -// is removed) -// -// This cant be called twice in a row without moving -// the iterator to the next item. If there is -// no current item this function throws an exception. -// -template -void tsSLIterRm::remove () -{ - if ( this->pCurrent == 0 || this->pPrevious == 0 ) { - throwWithLocation ( noCurrentItemInIterator () ); - } - - tsSLNode *pPrevNode = this->pPrevious; - tsSLNode *pCurNode = this->pCurrent; - - pPrevNode->pNext = pCurNode->pNext; - this->pCurrent = this->pPrevious; - this->pPrevious = 0; -} #endif // tsSLListh