many improvements

This commit is contained in:
Jeff Hill
1996-11-02 01:07:24 +00:00
parent 77c34614a2
commit c83ef56154
12 changed files with 616 additions and 358 deletions

View File

@@ -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 <stdio.h>
#include <limits.h>
#include <string.h>
#include <math.h>
@@ -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 T, class ID>
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; nbits<resTableIndexBitWidth; nbits++) {
this->hashIdMask = (1<<nbits) - 1;
if ( ((nHashTableEntries-1) & ~this->hashIdMask) == 0){
break;
}
}
this->hashIdNBits = nbits;
this->nInUse = 0u;
this->pTable = new tsSLList<T> [this->hashIdMask+1u];
if (!pTable) {
return -1;
}
return 0;
}
int init(unsigned nHashTableEntries);
~resTable()
{
@@ -105,78 +87,18 @@ public:
}
}
void destroyAllEntries()
{
tsSLList<T> *pList = this->pTable;
void destroyAllEntries();
while (pList<&this->pTable[this->hashIdMask+1]) {
tsSLIter<T> iter(*pList);
T *pItem;
while ( (pItem = iter()) ) {
iter.remove();
delete pItem;
this->nInUse--;
}
pList++;
}
}
void show (unsigned level);
void show (unsigned level)
{
tsSLList<T> *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<T> 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<T> &list = this->pTable[this->hash(res)];
tsSLIter<T> 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<T> iter(this->pTable[this->hash(idIn)]);
T *pCur;
this->find(iter, idIn);
pCur = iter.current();
if (pCur) {
this->nInUse--;
iter.remove();
}
return pCur;
tsSLList<T> &list = this->pTable[this->hash(idIn)];
return this->find(list, idIn, rtdfDelete);
}
T *lookup (const ID &idIn)
{
tsSLIter<T> iter(this->pTable[this->hash(idIn)]);
this->find(iter, idIn);
return iter.current();
tsSLList<T> &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<T> &iter, const ID &idIn)
T *find (tsSLList<T> &list, const ID &idIn,
resTableDelFlag df=rtdfNoDelete)
{
tsSLIter<T> 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

View File

@@ -26,13 +26,13 @@ private:
main ()
{
tsDLList<fred> list;
tsDLIter<fred> iter(list);
fred *pFred;
unsigned i;
clock_t clk;
clock_t diff;
double delay;
tsDLList<fred> list;
tsDLFwdIter<fred> iter(list);
fred *pFred;
unsigned i;
clock_t clk;
clock_t diff;
double delay;
for (i=0; i<LOOPCOUNT; i++) {
pFred = new fred();

View File

@@ -21,14 +21,15 @@ private:
main ()
{
tsDLList<fred> list;
tsDLIter<fred> iter(list);
fred *pFred;
fred *pFredII;
fred *pFredBack;
tsDLList<jane> janeList;
tsDLIter<jane> janeIter(janeList);
jane *pJane;
tsDLList<fred> list;
tsDLFwdIter<fred> iter(list);
fred *pFred;
fred *pFredII;
fred *pFredBack;
tsDLList<jane> janeList;
tsDLFwdIter<jane> janeFwdIter(janeList);
tsDLBwdIter<jane> 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);
}

View File

@@ -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);
}

View File

@@ -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 T>
class tsDLList {
friend class tsDLIter<T>;
friend class tsDLFwdIter<T>;
friend class tsDLBwdIter<T>;
private:
//
// clear()
@@ -280,6 +285,8 @@ template <class T>
class tsDLNode {
friend class tsDLList<T>;
friend class tsDLIter<T>;
friend class tsDLFwdIter<T>;
friend class tsDLBwdIter<T>;
public:
tsDLNode() : pNext(0), pPrev(0) {}
//
@@ -299,11 +306,19 @@ private:
//
// tsDLIter<T>
//
// 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 T>
class tsDLIter {
public:
tsDLIter(tsDLList<T> &listIn) :
pList(&listIn), pCurrent(0) {}
tsDLIter (const tsDLList<T> &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<T>::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<T>::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<T> *pList;
};
//
// tsDLFwdIter<T>
//
// 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 T>
class tsDLFwdIter: private tsDLIter<T> {
public:
tsDLFwdIter (tsDLList<T> &listIn) :
tsDLIter<T>(listIn) {}
void reset ()
{
this->tsDLIter<T>::reset();
}
void reset (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
void operator = (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
T * operator () ()
{
return this->tsDLIter<T>::next();
}
T * next ()
{
return this->tsDLIter<T>::next();
}
T * first()
{
return this->tsDLIter<T>::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<T> *pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the previous item
//
this->pCurrent = pCur->tsDLNode<T>::pPrev;
//
// delete current item
//
this->pList->remove(*pCur);
pMutableList->remove(*pCur);
}
}
protected:
tsDLList<T> *getList() { return pList; }
private:
tsDLList<T> *pList;
T *pCurrent;
};
//
// tsDLBwdIter<T>
//
// 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 T>
class tsDLBwdIter : private tsDLIter<T> {
public:
tsDLBwdIter(tsDLList<T> &listIn) :
tsDLIter<T>(&listIn) {}
void reset ()
{
this->tsDLIter<T>::reset();
}
void reset (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
void operator = (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
T * operator () ()
{
return this->tsDLIter<T>::prev();
}
T * prev ()
{
return this->tsDLIter<T>::prev();
}
T * last()
{
return this->tsDLIter<T>::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<T> *pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the item after the
// item being deleted
//
this->pCurrent = pCur->tsDLNode<T>::pNext;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
};
//
// find
// returns -1 if the item isnt on the list
@@ -405,11 +554,11 @@ private:
template <class T>
inline int tsDLList<T>::find(T &item)
{
tsDLIter<T> iter(*this);
tsDLFwdIter<T> iter(*this);
tsDLNode<T> *pItem;
int itemNo=0;
while ( (pItem = iter()) ) {
while ( (pItem = iter.next()) ) {
if (pItem == &item) {
return itemNo;
}

View File

@@ -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 <assert.h>
#endif
//
// tsSLList<>
//
@@ -124,6 +131,15 @@ private:
T *pNext;
};
//
// tsDLFwdIter<T>
//
// 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 T>
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<T> * 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<T>::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<T> *pCurrent;
tsSLNode<T> *pPrevious;
tsSLList<T> *pList;
};

View File

@@ -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 <stdio.h>
#include <limits.h>
#include <string.h>
#include <math.h>
@@ -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 T, class ID>
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; nbits<resTableIndexBitWidth; nbits++) {
this->hashIdMask = (1<<nbits) - 1;
if ( ((nHashTableEntries-1) & ~this->hashIdMask) == 0){
break;
}
}
this->hashIdNBits = nbits;
this->nInUse = 0u;
this->pTable = new tsSLList<T> [this->hashIdMask+1u];
if (!pTable) {
return -1;
}
return 0;
}
int init(unsigned nHashTableEntries);
~resTable()
{
@@ -105,78 +87,18 @@ public:
}
}
void destroyAllEntries()
{
tsSLList<T> *pList = this->pTable;
void destroyAllEntries();
while (pList<&this->pTable[this->hashIdMask+1]) {
tsSLIter<T> iter(*pList);
T *pItem;
while ( (pItem = iter()) ) {
iter.remove();
delete pItem;
this->nInUse--;
}
pList++;
}
}
void show (unsigned level);
void show (unsigned level)
{
tsSLList<T> *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<T> 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<T> &list = this->pTable[this->hash(res)];
tsSLIter<T> 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<T> iter(this->pTable[this->hash(idIn)]);
T *pCur;
this->find(iter, idIn);
pCur = iter.current();
if (pCur) {
this->nInUse--;
iter.remove();
}
return pCur;
tsSLList<T> &list = this->pTable[this->hash(idIn)];
return this->find(list, idIn, rtdfDelete);
}
T *lookup (const ID &idIn)
{
tsSLIter<T> iter(this->pTable[this->hash(idIn)]);
this->find(iter, idIn);
return iter.current();
tsSLList<T> &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<T> &iter, const ID &idIn)
T *find (tsSLList<T> &list, const ID &idIn,
resTableDelFlag df=rtdfNoDelete)
{
tsSLIter<T> 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

View File

@@ -26,13 +26,13 @@ private:
main ()
{
tsDLList<fred> list;
tsDLIter<fred> iter(list);
fred *pFred;
unsigned i;
clock_t clk;
clock_t diff;
double delay;
tsDLList<fred> list;
tsDLFwdIter<fred> iter(list);
fred *pFred;
unsigned i;
clock_t clk;
clock_t diff;
double delay;
for (i=0; i<LOOPCOUNT; i++) {
pFred = new fred();

View File

@@ -21,14 +21,15 @@ private:
main ()
{
tsDLList<fred> list;
tsDLIter<fred> iter(list);
fred *pFred;
fred *pFredII;
fred *pFredBack;
tsDLList<jane> janeList;
tsDLIter<jane> janeIter(janeList);
jane *pJane;
tsDLList<fred> list;
tsDLFwdIter<fred> iter(list);
fred *pFred;
fred *pFredII;
fred *pFredBack;
tsDLList<jane> janeList;
tsDLFwdIter<jane> janeFwdIter(janeList);
tsDLBwdIter<jane> 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);
}

View File

@@ -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);
}

View File

@@ -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 T>
class tsDLList {
friend class tsDLIter<T>;
friend class tsDLFwdIter<T>;
friend class tsDLBwdIter<T>;
private:
//
// clear()
@@ -280,6 +285,8 @@ template <class T>
class tsDLNode {
friend class tsDLList<T>;
friend class tsDLIter<T>;
friend class tsDLFwdIter<T>;
friend class tsDLBwdIter<T>;
public:
tsDLNode() : pNext(0), pPrev(0) {}
//
@@ -299,11 +306,19 @@ private:
//
// tsDLIter<T>
//
// 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 T>
class tsDLIter {
public:
tsDLIter(tsDLList<T> &listIn) :
pList(&listIn), pCurrent(0) {}
tsDLIter (const tsDLList<T> &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<T>::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<T>::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<T> *pList;
};
//
// tsDLFwdIter<T>
//
// 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 T>
class tsDLFwdIter: private tsDLIter<T> {
public:
tsDLFwdIter (tsDLList<T> &listIn) :
tsDLIter<T>(listIn) {}
void reset ()
{
this->tsDLIter<T>::reset();
}
void reset (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
void operator = (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
T * operator () ()
{
return this->tsDLIter<T>::next();
}
T * next ()
{
return this->tsDLIter<T>::next();
}
T * first()
{
return this->tsDLIter<T>::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<T> *pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the previous item
//
this->pCurrent = pCur->tsDLNode<T>::pPrev;
//
// delete current item
//
this->pList->remove(*pCur);
pMutableList->remove(*pCur);
}
}
protected:
tsDLList<T> *getList() { return pList; }
private:
tsDLList<T> *pList;
T *pCurrent;
};
//
// tsDLBwdIter<T>
//
// 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 T>
class tsDLBwdIter : private tsDLIter<T> {
public:
tsDLBwdIter(tsDLList<T> &listIn) :
tsDLIter<T>(&listIn) {}
void reset ()
{
this->tsDLIter<T>::reset();
}
void reset (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
void operator = (tsDLList<T> &listIn)
{
this->tsDLIter<T>::reset(listIn);
}
T * operator () ()
{
return this->tsDLIter<T>::prev();
}
T * prev ()
{
return this->tsDLIter<T>::prev();
}
T * last()
{
return this->tsDLIter<T>::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<T> *pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the item after the
// item being deleted
//
this->pCurrent = pCur->tsDLNode<T>::pNext;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
};
//
// find
// returns -1 if the item isnt on the list
@@ -405,11 +554,11 @@ private:
template <class T>
inline int tsDLList<T>::find(T &item)
{
tsDLIter<T> iter(*this);
tsDLFwdIter<T> iter(*this);
tsDLNode<T> *pItem;
int itemNo=0;
while ( (pItem = iter()) ) {
while ( (pItem = iter.next()) ) {
if (pItem == &item) {
return itemNo;
}

View File

@@ -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 <assert.h>
#endif
//
// tsSLList<>
//
@@ -124,6 +131,15 @@ private:
T *pNext;
};
//
// tsDLFwdIter<T>
//
// 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 T>
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<T> * 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<T>::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<T> *pCurrent;
tsSLNode<T> *pPrevious;
tsSLList<T> *pList;
};