diff --git a/src/cxxTemplates/resourceLib.h b/src/cxxTemplates/resourceLib.h index f1a081370..42f85249b 100644 --- a/src/cxxTemplates/resourceLib.h +++ b/src/cxxTemplates/resourceLib.h @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.5 1996/09/04 19:57:06 jhill + * string id resource now copies id + * * Revision 1.4 1996/08/05 19:31:59 jhill * fixed removes use of iter.cur() * @@ -50,6 +53,7 @@ #ifndef INCresourceLibh #define INCresourceLibh +#include #include #include #include @@ -59,7 +63,7 @@ typedef int resLibStatus; typedef unsigned resTableIndex; -const unsigned resTableIndexBitWidth = (sizeof(resTableIndex)*CHAR_BIT); +#define resTableIndexBitWidth (sizeof(resTableIndex)*CHAR_BIT) // // class T must derive class ID @@ -67,34 +71,12 @@ const unsigned resTableIndexBitWidth = (sizeof(resTableIndex)*CHAR_BIT); template class resTable { public: + enum resTableDelFlag {rtdfDelete, rtdfNoDelete}; + resTable() : pTable(0), hashIdMask(0), hashIdNBits(0), nInUse(0) {} - int init(unsigned nHashTableEntries) - { - unsigned nbits; - - if (nHashTableEntries<1u) { - return -1; - } - - // - // count the number of bits in the hash index - // - for (nbits=0; nbitshashIdMask = (1<hashIdMask) == 0){ - break; - } - } - this->hashIdNBits = nbits; - this->nInUse = 0u; - this->pTable = new tsSLList [this->hashIdMask+1u]; - if (!pTable) { - return -1; - } - return 0; - } + int init(unsigned nHashTableEntries); ~resTable() { @@ -105,78 +87,18 @@ public: } } - void destroyAllEntries() - { - tsSLList *pList = this->pTable; + void destroyAllEntries(); - while (pList<&this->pTable[this->hashIdMask+1]) { - tsSLIter iter(*pList); - T *pItem; - while ( (pItem = iter()) ) { - iter.remove(); - delete pItem; - this->nInUse--; - } - pList++; - } - } + void show (unsigned level); - void show (unsigned level) - { - tsSLList *pList; - double X; - double XX; - double mean; - double stdDev; - unsigned maxEntries; - - printf("resTable with %d resources installed\n", this->nInUse); - - if (level >=1u) { - pList = this->pTable; - X = 0.0; - XX = 0.0; - maxEntries = 0; - while (pList < &this->pTable[this->hashIdMask+1]) { - unsigned count; - tsSLIter iter(*pList); - T *pItem; - - count = 0; - while ( (pItem = iter()) ) { - if (level >= 3u) { - pItem->show (level); - } - count++; - } - X += count; - XX += count*count; - if (count>maxEntries) { - maxEntries = count; - } - pList++; - } - - mean = X/(this->hashIdMask+1); - stdDev = sqrt(XX/(this->hashIdMask+1)- mean*mean); - printf( - "entries/table index - mean = %f std dev = %f max = %d\n", - mean, stdDev, maxEntries); - } - } - - -public: int add (T &res) { // // T must derive from ID // tsSLList &list = this->pTable[this->hash(res)]; - tsSLIter iter(list); - this->find(iter, res); - if (iter.current()) { + if (this->find(list, res) != 0) { return -1; } list.add(res); @@ -186,25 +108,15 @@ public: T *remove (const ID &idIn) { - tsSLIter iter(this->pTable[this->hash(idIn)]); - T *pCur; - - this->find(iter, idIn); - pCur = iter.current(); - if (pCur) { - this->nInUse--; - iter.remove(); - } - return pCur; + tsSLList &list = this->pTable[this->hash(idIn)]; + return this->find(list, idIn, rtdfDelete); } T *lookup (const ID &idIn) { - tsSLIter iter(this->pTable[this->hash(idIn)]); - - this->find(iter, idIn); - return iter.current(); + tsSLList &list = this->pTable[this->hash(idIn)]; + return this->find(list, idIn); } private: @@ -228,18 +140,24 @@ private: // iterator points to the item found upon return // (or NULL if nothing matching was found) // - void find (tsSLIter &iter, const ID &idIn) + T *find (tsSLList &list, const ID &idIn, + resTableDelFlag df=rtdfNoDelete) { + tsSLIter iter(list); T *pItem; ID *pId; while ( (pItem = iter()) ) { pId = pItem; if (*pId == idIn) { + if (df==rtdfDelete) { + iter.remove(); + this->nInUse--; + } break; } } - return; + return pItem; } }; @@ -426,5 +344,9 @@ private: char * const pStr; }; +#if defined(__SUNPRO_CC) || defined(EXPAND_TEMPLATES_HERE) +# include "resourceLib.cc" +#endif + #endif // INCresourceLibh diff --git a/src/cxxTemplates/test/tsDLListBench.cc b/src/cxxTemplates/test/tsDLListBench.cc index b9bd55352..07c377747 100644 --- a/src/cxxTemplates/test/tsDLListBench.cc +++ b/src/cxxTemplates/test/tsDLListBench.cc @@ -26,13 +26,13 @@ private: main () { - tsDLList list; - tsDLIter iter(list); - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; + tsDLList list; + tsDLFwdIter iter(list); + fred *pFred; + unsigned i; + clock_t clk; + clock_t diff; + double delay; for (i=0; i list; - tsDLIter iter(list); - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsDLList janeList; - tsDLIter janeIter(janeList); - jane *pJane; + tsDLList list; + tsDLFwdIter iter(list); + fred *pFred; + fred *pFredII; + fred *pFredBack; + tsDLList janeList; + tsDLFwdIter janeFwdIter(janeList); + tsDLBwdIter janeBwdIter(janeList); + jane *pJane; pFred = new fred("A"); pFredII = new fred("B"); @@ -61,7 +62,11 @@ main () pJane = new jane("JB"); janeList.add(*pJane); - while (pJane = janeIter()) { + while (pJane = janeFwdIter()) { + pJane->show(); + } + + while (pJane = janeBwdIter()) { pJane->show(); } @@ -69,5 +74,27 @@ main () while (pFredBack = iter()) { pFredBack->show(); } + + iter = list; + while (pFredBack = iter()) { + iter.remove(); + } + assert(list.count()==0); + + janeFwdIter = janeList; + while (pFredBack = janeFwdIter()) { + janeFwdIter.remove(); + } + assert(janeList.count()==0); + + pJane = new jane("JA"); + janeList.add(*pJane); + pJane = new jane("JB"); + janeList.add(*pJane); + janeBwdIter = janeList; + while (pFredBack = janeBwdIter()) { + janeBwdIter.remove(); + } + assert(janeList.count()==0); } diff --git a/src/cxxTemplates/test/tsSLListTest.cc b/src/cxxTemplates/test/tsSLListTest.cc index de3750f58..0dbd1db71 100644 --- a/src/cxxTemplates/test/tsSLListTest.cc +++ b/src/cxxTemplates/test/tsSLListTest.cc @@ -46,9 +46,9 @@ main () list.add(*pFredII); list.add(*pFred); iter.reset(); - pFredBack = iter(); - iter.remove(); - iter.remove(); + while ( (pFredBack = iter()) ) { + iter.remove(); + } pFredBack = list.get(); assert (pFredBack == 0); list.add(*pFred); @@ -72,5 +72,12 @@ main () while (pFredBack = iter()) { pFredBack->show(); } + + while (pFredBack = iter()) { + iter.remove(); + } + + pFredBack = iter(); + assert(pFredBack==NULL); } diff --git a/src/cxxTemplates/tsDLList.h b/src/cxxTemplates/tsDLList.h index 7de4d4699..a943194ce 100644 --- a/src/cxxTemplates/tsDLList.h +++ b/src/cxxTemplates/tsDLList.h @@ -31,6 +31,9 @@ * * History * $Log$ + * Revision 1.4 1996/08/14 12:32:09 jbk + * added first() to list class, added first()/last() to iterator. + * * Revision 1.3 1996/07/25 18:01:41 jhill * use pointer (not ref) for list in iter class * @@ -52,6 +55,8 @@ template class tsDLList { friend class tsDLIter; +friend class tsDLFwdIter; +friend class tsDLBwdIter; private: // // clear() @@ -280,6 +285,8 @@ template class tsDLNode { friend class tsDLList; friend class tsDLIter; +friend class tsDLFwdIter; +friend class tsDLBwdIter; public: tsDLNode() : pNext(0), pPrev(0) {} // @@ -299,11 +306,19 @@ private: // // tsDLIter // +// Notes: +// 2) This iterator does not allow for removal +// of an item in order to avoid problems +// resulting when we remove an item (and +// then dont know whether to make pCurrent +// point at the item before or after the +// item removed +// template class tsDLIter { public: - tsDLIter(tsDLList &listIn) : - pList(&listIn), pCurrent(0) {} + tsDLIter (const tsDLList &listIn) : + pCurrent(0), pList(&listIn) {} void reset () { @@ -321,24 +336,6 @@ public: this->reset(listIn); } - T * current () - { - return this->pCurrent; - } - - T * prev () - { - T *pCur = this->pCurrent; - if (pCur==0) { - pCur = this->pList->pLast; - } - else { - pCur = pCur->tsDLNode::pPrev; - } - this->pCurrent = pCur; - return pCur; - } - T * next () { T *pCur = this->pCurrent; @@ -352,50 +349,202 @@ public: return pCur; } + T * prev () + { + T *pCur = this->pCurrent; + if (pCur==0) { + pCur = this->pList->pLast; + } + else { + pCur = pCur->tsDLNode::pPrev; + } + this->pCurrent = pCur; + return pCur; + } + T * first() { this->pCurrent = this->pList->pFirst; return this->pCurrent; } - T * last() - { - this->pCurrent = this->pList->pLast; - return this->pCurrent; - } + T * last() + { + this->pCurrent = this->pList->pLast; + return this->pCurrent; + } T * operator () () { return this->next(); } +protected: + T *pCurrent; + const tsDLList *pList; +}; + +// +// tsDLFwdIter +// +// 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) +// +// 2) This iterator only moves forward in order to +// avoid problems resulting when we remove an +// item (and then dont know whether to make +// pCurrent point at the item before or after +// the item removed +// +template +class tsDLFwdIter: private tsDLIter { +public: + tsDLFwdIter (tsDLList &listIn) : + tsDLIter(listIn) {} + + void reset () + { + this->tsDLIter::reset(); + } + void reset (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + void operator = (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + T * operator () () + { + return this->tsDLIter::next(); + } + T * next () + { + return this->tsDLIter::next(); + } + T * first() + { + return this->tsDLIter::first(); + } + // // remove () - // remove current item - // (and move current to be the next item - // in the list) + // (and move current to be the item + // pointed to by pPrev - 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) // void remove () { T *pCur = this->pCurrent; + if (pCur) { // - // move current to the next item + // strip const // - this->next(); + tsDLList *pMutableList = + (tsDLList *) this->pList; + + // + // Move this->pCurrent to the previous item + // + this->pCurrent = pCur->tsDLNode::pPrev; + // // delete current item // - this->pList->remove(*pCur); + pMutableList->remove(*pCur); } } -protected: - tsDLList *getList() { return pList; } -private: - tsDLList *pList; - T *pCurrent; }; +// +// tsDLBwdIter +// +// 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) +// +// 2) This iterator only moves backward in order to +// avoid problems resulting when we remove an +// item (and then dont know whether to make +// pCurrent point at the item before or after +// the item removed +// +template +class tsDLBwdIter : private tsDLIter { +public: + tsDLBwdIter(tsDLList &listIn) : + tsDLIter(&listIn) {} + + void reset () + { + this->tsDLIter::reset(); + } + void reset (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + void operator = (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + T * operator () () + { + return this->tsDLIter::prev(); + } + T * prev () + { + return this->tsDLIter::prev(); + } + T * last() + { + return this->tsDLIter::last(); + } + + // + // remove () + // remove current item + // (and move current to be the item + // pointed to by pNext - 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) + // + void remove () + { + T *pCur = this->pCurrent; + + if (pCur) { + // + // strip const + // + tsDLList *pMutableList = + (tsDLList *) this->pList; + + // + // Move this->pCurrent to the item after the + // item being deleted + // + this->pCurrent = pCur->tsDLNode::pNext; + + // + // delete current item + // + pMutableList->remove(*pCur); + } + } +}; + + // // find // returns -1 if the item isnt on the list @@ -405,11 +554,11 @@ private: template inline int tsDLList::find(T &item) { - tsDLIter iter(*this); + tsDLFwdIter iter(*this); tsDLNode *pItem; int itemNo=0; - while ( (pItem = iter()) ) { + while ( (pItem = iter.next()) ) { if (pItem == &item) { return itemNo; } diff --git a/src/cxxTemplates/tsSLList.h b/src/cxxTemplates/tsSLList.h index 66002b6b7..056de8391 100644 --- a/src/cxxTemplates/tsSLList.h +++ b/src/cxxTemplates/tsSLList.h @@ -31,6 +31,9 @@ * * History * $Log$ + * Revision 1.4 1996/09/04 19:57:07 jhill + * string id resource now copies id + * * Revision 1.3 1996/07/25 18:01:42 jhill * use pointer (not ref) for list in iter class * @@ -43,6 +46,10 @@ * */ +#ifndef assert // allows epicsAssert.h +#include +#endif + // // tsSLList<> // @@ -124,6 +131,15 @@ private: T *pNext; }; +// +// tsDLFwdIter +// +// 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) +// template class tsSLIter { public: @@ -147,29 +163,25 @@ public: this->reset(listIn); } - T * current () - { - return this->pCurrent; - } - + // + // move iterator forward + // T * next () { + T *pNewCur; if (this->pCurrent) { this->pPrevious = this->pCurrent; } else { this->pPrevious = this->pList; } - this->pCurrent = this->pPrevious->pNext; - return this->pCurrent; + this->pCurrent = pNewCur = this->pPrevious->pNext; + return pNewCur; } - // this should move current? - //tsSLNode * prev () const - //{ - // return this->pPrevious; - //} - + // + // move iterator forward + // T * operator () () { return this->next(); @@ -177,17 +189,29 @@ public: // // remove current node + // (and move current to be the previos 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) + // + // **** NOTE **** + // This may be called once for each cycle of the + // iterator. Attempts to call this twice without + // moving the iterator forward inbetween the two + // calls will assert fail // void remove () { if (this->pCurrent) { - this->pCurrent = - this->pCurrent->tsSLNode::pNext; - this->pPrevious->pNext = this->pCurrent; + assert(this->pPrevious); + this->pPrevious->pNext = this->pCurrent->pNext; + this->pCurrent = this->pPrevious; + this->pPrevious = 0; } } private: - T *pCurrent; + tsSLNode *pCurrent; tsSLNode *pPrevious; tsSLList *pList; }; diff --git a/src/libCom/cxxTemplates/resourceLib.h b/src/libCom/cxxTemplates/resourceLib.h index f1a081370..42f85249b 100644 --- a/src/libCom/cxxTemplates/resourceLib.h +++ b/src/libCom/cxxTemplates/resourceLib.h @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.5 1996/09/04 19:57:06 jhill + * string id resource now copies id + * * Revision 1.4 1996/08/05 19:31:59 jhill * fixed removes use of iter.cur() * @@ -50,6 +53,7 @@ #ifndef INCresourceLibh #define INCresourceLibh +#include #include #include #include @@ -59,7 +63,7 @@ typedef int resLibStatus; typedef unsigned resTableIndex; -const unsigned resTableIndexBitWidth = (sizeof(resTableIndex)*CHAR_BIT); +#define resTableIndexBitWidth (sizeof(resTableIndex)*CHAR_BIT) // // class T must derive class ID @@ -67,34 +71,12 @@ const unsigned resTableIndexBitWidth = (sizeof(resTableIndex)*CHAR_BIT); template class resTable { public: + enum resTableDelFlag {rtdfDelete, rtdfNoDelete}; + resTable() : pTable(0), hashIdMask(0), hashIdNBits(0), nInUse(0) {} - int init(unsigned nHashTableEntries) - { - unsigned nbits; - - if (nHashTableEntries<1u) { - return -1; - } - - // - // count the number of bits in the hash index - // - for (nbits=0; nbitshashIdMask = (1<hashIdMask) == 0){ - break; - } - } - this->hashIdNBits = nbits; - this->nInUse = 0u; - this->pTable = new tsSLList [this->hashIdMask+1u]; - if (!pTable) { - return -1; - } - return 0; - } + int init(unsigned nHashTableEntries); ~resTable() { @@ -105,78 +87,18 @@ public: } } - void destroyAllEntries() - { - tsSLList *pList = this->pTable; + void destroyAllEntries(); - while (pList<&this->pTable[this->hashIdMask+1]) { - tsSLIter iter(*pList); - T *pItem; - while ( (pItem = iter()) ) { - iter.remove(); - delete pItem; - this->nInUse--; - } - pList++; - } - } + void show (unsigned level); - void show (unsigned level) - { - tsSLList *pList; - double X; - double XX; - double mean; - double stdDev; - unsigned maxEntries; - - printf("resTable with %d resources installed\n", this->nInUse); - - if (level >=1u) { - pList = this->pTable; - X = 0.0; - XX = 0.0; - maxEntries = 0; - while (pList < &this->pTable[this->hashIdMask+1]) { - unsigned count; - tsSLIter iter(*pList); - T *pItem; - - count = 0; - while ( (pItem = iter()) ) { - if (level >= 3u) { - pItem->show (level); - } - count++; - } - X += count; - XX += count*count; - if (count>maxEntries) { - maxEntries = count; - } - pList++; - } - - mean = X/(this->hashIdMask+1); - stdDev = sqrt(XX/(this->hashIdMask+1)- mean*mean); - printf( - "entries/table index - mean = %f std dev = %f max = %d\n", - mean, stdDev, maxEntries); - } - } - - -public: int add (T &res) { // // T must derive from ID // tsSLList &list = this->pTable[this->hash(res)]; - tsSLIter iter(list); - this->find(iter, res); - if (iter.current()) { + if (this->find(list, res) != 0) { return -1; } list.add(res); @@ -186,25 +108,15 @@ public: T *remove (const ID &idIn) { - tsSLIter iter(this->pTable[this->hash(idIn)]); - T *pCur; - - this->find(iter, idIn); - pCur = iter.current(); - if (pCur) { - this->nInUse--; - iter.remove(); - } - return pCur; + tsSLList &list = this->pTable[this->hash(idIn)]; + return this->find(list, idIn, rtdfDelete); } T *lookup (const ID &idIn) { - tsSLIter iter(this->pTable[this->hash(idIn)]); - - this->find(iter, idIn); - return iter.current(); + tsSLList &list = this->pTable[this->hash(idIn)]; + return this->find(list, idIn); } private: @@ -228,18 +140,24 @@ private: // iterator points to the item found upon return // (or NULL if nothing matching was found) // - void find (tsSLIter &iter, const ID &idIn) + T *find (tsSLList &list, const ID &idIn, + resTableDelFlag df=rtdfNoDelete) { + tsSLIter iter(list); T *pItem; ID *pId; while ( (pItem = iter()) ) { pId = pItem; if (*pId == idIn) { + if (df==rtdfDelete) { + iter.remove(); + this->nInUse--; + } break; } } - return; + return pItem; } }; @@ -426,5 +344,9 @@ private: char * const pStr; }; +#if defined(__SUNPRO_CC) || defined(EXPAND_TEMPLATES_HERE) +# include "resourceLib.cc" +#endif + #endif // INCresourceLibh diff --git a/src/libCom/cxxTemplates/test/tsDLListBench.cc b/src/libCom/cxxTemplates/test/tsDLListBench.cc index b9bd55352..07c377747 100644 --- a/src/libCom/cxxTemplates/test/tsDLListBench.cc +++ b/src/libCom/cxxTemplates/test/tsDLListBench.cc @@ -26,13 +26,13 @@ private: main () { - tsDLList list; - tsDLIter iter(list); - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; + tsDLList list; + tsDLFwdIter iter(list); + fred *pFred; + unsigned i; + clock_t clk; + clock_t diff; + double delay; for (i=0; i list; - tsDLIter iter(list); - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsDLList janeList; - tsDLIter janeIter(janeList); - jane *pJane; + tsDLList list; + tsDLFwdIter iter(list); + fred *pFred; + fred *pFredII; + fred *pFredBack; + tsDLList janeList; + tsDLFwdIter janeFwdIter(janeList); + tsDLBwdIter janeBwdIter(janeList); + jane *pJane; pFred = new fred("A"); pFredII = new fred("B"); @@ -61,7 +62,11 @@ main () pJane = new jane("JB"); janeList.add(*pJane); - while (pJane = janeIter()) { + while (pJane = janeFwdIter()) { + pJane->show(); + } + + while (pJane = janeBwdIter()) { pJane->show(); } @@ -69,5 +74,27 @@ main () while (pFredBack = iter()) { pFredBack->show(); } + + iter = list; + while (pFredBack = iter()) { + iter.remove(); + } + assert(list.count()==0); + + janeFwdIter = janeList; + while (pFredBack = janeFwdIter()) { + janeFwdIter.remove(); + } + assert(janeList.count()==0); + + pJane = new jane("JA"); + janeList.add(*pJane); + pJane = new jane("JB"); + janeList.add(*pJane); + janeBwdIter = janeList; + while (pFredBack = janeBwdIter()) { + janeBwdIter.remove(); + } + assert(janeList.count()==0); } diff --git a/src/libCom/cxxTemplates/test/tsSLListTest.cc b/src/libCom/cxxTemplates/test/tsSLListTest.cc index de3750f58..0dbd1db71 100644 --- a/src/libCom/cxxTemplates/test/tsSLListTest.cc +++ b/src/libCom/cxxTemplates/test/tsSLListTest.cc @@ -46,9 +46,9 @@ main () list.add(*pFredII); list.add(*pFred); iter.reset(); - pFredBack = iter(); - iter.remove(); - iter.remove(); + while ( (pFredBack = iter()) ) { + iter.remove(); + } pFredBack = list.get(); assert (pFredBack == 0); list.add(*pFred); @@ -72,5 +72,12 @@ main () while (pFredBack = iter()) { pFredBack->show(); } + + while (pFredBack = iter()) { + iter.remove(); + } + + pFredBack = iter(); + assert(pFredBack==NULL); } diff --git a/src/libCom/cxxTemplates/tsDLList.h b/src/libCom/cxxTemplates/tsDLList.h index 7de4d4699..a943194ce 100644 --- a/src/libCom/cxxTemplates/tsDLList.h +++ b/src/libCom/cxxTemplates/tsDLList.h @@ -31,6 +31,9 @@ * * History * $Log$ + * Revision 1.4 1996/08/14 12:32:09 jbk + * added first() to list class, added first()/last() to iterator. + * * Revision 1.3 1996/07/25 18:01:41 jhill * use pointer (not ref) for list in iter class * @@ -52,6 +55,8 @@ template class tsDLList { friend class tsDLIter; +friend class tsDLFwdIter; +friend class tsDLBwdIter; private: // // clear() @@ -280,6 +285,8 @@ template class tsDLNode { friend class tsDLList; friend class tsDLIter; +friend class tsDLFwdIter; +friend class tsDLBwdIter; public: tsDLNode() : pNext(0), pPrev(0) {} // @@ -299,11 +306,19 @@ private: // // tsDLIter // +// Notes: +// 2) This iterator does not allow for removal +// of an item in order to avoid problems +// resulting when we remove an item (and +// then dont know whether to make pCurrent +// point at the item before or after the +// item removed +// template class tsDLIter { public: - tsDLIter(tsDLList &listIn) : - pList(&listIn), pCurrent(0) {} + tsDLIter (const tsDLList &listIn) : + pCurrent(0), pList(&listIn) {} void reset () { @@ -321,24 +336,6 @@ public: this->reset(listIn); } - T * current () - { - return this->pCurrent; - } - - T * prev () - { - T *pCur = this->pCurrent; - if (pCur==0) { - pCur = this->pList->pLast; - } - else { - pCur = pCur->tsDLNode::pPrev; - } - this->pCurrent = pCur; - return pCur; - } - T * next () { T *pCur = this->pCurrent; @@ -352,50 +349,202 @@ public: return pCur; } + T * prev () + { + T *pCur = this->pCurrent; + if (pCur==0) { + pCur = this->pList->pLast; + } + else { + pCur = pCur->tsDLNode::pPrev; + } + this->pCurrent = pCur; + return pCur; + } + T * first() { this->pCurrent = this->pList->pFirst; return this->pCurrent; } - T * last() - { - this->pCurrent = this->pList->pLast; - return this->pCurrent; - } + T * last() + { + this->pCurrent = this->pList->pLast; + return this->pCurrent; + } T * operator () () { return this->next(); } +protected: + T *pCurrent; + const tsDLList *pList; +}; + +// +// tsDLFwdIter +// +// 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) +// +// 2) This iterator only moves forward in order to +// avoid problems resulting when we remove an +// item (and then dont know whether to make +// pCurrent point at the item before or after +// the item removed +// +template +class tsDLFwdIter: private tsDLIter { +public: + tsDLFwdIter (tsDLList &listIn) : + tsDLIter(listIn) {} + + void reset () + { + this->tsDLIter::reset(); + } + void reset (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + void operator = (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + T * operator () () + { + return this->tsDLIter::next(); + } + T * next () + { + return this->tsDLIter::next(); + } + T * first() + { + return this->tsDLIter::first(); + } + // // remove () - // remove current item - // (and move current to be the next item - // in the list) + // (and move current to be the item + // pointed to by pPrev - 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) // void remove () { T *pCur = this->pCurrent; + if (pCur) { // - // move current to the next item + // strip const // - this->next(); + tsDLList *pMutableList = + (tsDLList *) this->pList; + + // + // Move this->pCurrent to the previous item + // + this->pCurrent = pCur->tsDLNode::pPrev; + // // delete current item // - this->pList->remove(*pCur); + pMutableList->remove(*pCur); } } -protected: - tsDLList *getList() { return pList; } -private: - tsDLList *pList; - T *pCurrent; }; +// +// tsDLBwdIter +// +// 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) +// +// 2) This iterator only moves backward in order to +// avoid problems resulting when we remove an +// item (and then dont know whether to make +// pCurrent point at the item before or after +// the item removed +// +template +class tsDLBwdIter : private tsDLIter { +public: + tsDLBwdIter(tsDLList &listIn) : + tsDLIter(&listIn) {} + + void reset () + { + this->tsDLIter::reset(); + } + void reset (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + void operator = (tsDLList &listIn) + { + this->tsDLIter::reset(listIn); + } + T * operator () () + { + return this->tsDLIter::prev(); + } + T * prev () + { + return this->tsDLIter::prev(); + } + T * last() + { + return this->tsDLIter::last(); + } + + // + // remove () + // remove current item + // (and move current to be the item + // pointed to by pNext - 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) + // + void remove () + { + T *pCur = this->pCurrent; + + if (pCur) { + // + // strip const + // + tsDLList *pMutableList = + (tsDLList *) this->pList; + + // + // Move this->pCurrent to the item after the + // item being deleted + // + this->pCurrent = pCur->tsDLNode::pNext; + + // + // delete current item + // + pMutableList->remove(*pCur); + } + } +}; + + // // find // returns -1 if the item isnt on the list @@ -405,11 +554,11 @@ private: template inline int tsDLList::find(T &item) { - tsDLIter iter(*this); + tsDLFwdIter iter(*this); tsDLNode *pItem; int itemNo=0; - while ( (pItem = iter()) ) { + while ( (pItem = iter.next()) ) { if (pItem == &item) { return itemNo; } diff --git a/src/libCom/cxxTemplates/tsSLList.h b/src/libCom/cxxTemplates/tsSLList.h index 66002b6b7..056de8391 100644 --- a/src/libCom/cxxTemplates/tsSLList.h +++ b/src/libCom/cxxTemplates/tsSLList.h @@ -31,6 +31,9 @@ * * History * $Log$ + * Revision 1.4 1996/09/04 19:57:07 jhill + * string id resource now copies id + * * Revision 1.3 1996/07/25 18:01:42 jhill * use pointer (not ref) for list in iter class * @@ -43,6 +46,10 @@ * */ +#ifndef assert // allows epicsAssert.h +#include +#endif + // // tsSLList<> // @@ -124,6 +131,15 @@ private: T *pNext; }; +// +// tsDLFwdIter +// +// 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) +// template class tsSLIter { public: @@ -147,29 +163,25 @@ public: this->reset(listIn); } - T * current () - { - return this->pCurrent; - } - + // + // move iterator forward + // T * next () { + T *pNewCur; if (this->pCurrent) { this->pPrevious = this->pCurrent; } else { this->pPrevious = this->pList; } - this->pCurrent = this->pPrevious->pNext; - return this->pCurrent; + this->pCurrent = pNewCur = this->pPrevious->pNext; + return pNewCur; } - // this should move current? - //tsSLNode * prev () const - //{ - // return this->pPrevious; - //} - + // + // move iterator forward + // T * operator () () { return this->next(); @@ -177,17 +189,29 @@ public: // // remove current node + // (and move current to be the previos 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) + // + // **** NOTE **** + // This may be called once for each cycle of the + // iterator. Attempts to call this twice without + // moving the iterator forward inbetween the two + // calls will assert fail // void remove () { if (this->pCurrent) { - this->pCurrent = - this->pCurrent->tsSLNode::pNext; - this->pPrevious->pNext = this->pCurrent; + assert(this->pPrevious); + this->pPrevious->pNext = this->pCurrent->pNext; + this->pCurrent = this->pPrevious; + this->pPrevious = 0; } } private: - T *pCurrent; + tsSLNode *pCurrent; tsSLNode *pPrevious; tsSLList *pList; };