attempted to clean up HP-UX warnings

This commit is contained in:
Jeff Hill
1998-10-23 00:20:41 +00:00
parent 5eab74508e
commit 4ae1a330bd
6 changed files with 1310 additions and 844 deletions

View File

@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.17 1998/06/16 03:00:19 jhill
* cleaned up fast string hash table
*
* Revision 1.16 1998/04/10 23:07:33 jhill
* fixed solaris architecture specific problem where xxx>>32 was ignored
*
@@ -129,14 +132,7 @@ public:
int init(unsigned nHashTableEntries);
~resTable()
{
if (this->pTable) {
this->destroyAllEntries();
assert (this->nInUse == 0u);
delete [] this->pTable;
}
}
virtual ~resTable();
//
// destroy all res in the table
@@ -240,6 +236,7 @@ private:
class epicsShareClass uintId {
public:
uintId (unsigned idIn=UINT_MAX) : id(idIn) {}
virtual ~uintId();
int operator == (const uintId &idIn)
{
@@ -259,38 +256,6 @@ protected:
unsigned id;
};
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// uintId::resourceHash()
//
resTableIndex uintId::resourceHash(unsigned /* nBitsId */) const
{
resTableIndex hashid = this->id;
//
// This assumes worst case hash table index width of 1 bit.
// We will iterate this loop 5 times on a 32 bit architecture.
//
// A good optimizer will unroll this loop?
// Experiments using the microsoft compiler show that this isnt
// slower than switching on the architecture size and urolling the
// loop explicitly (that solution has resulted in portability
// problems in the past).
//
for (unsigned i=(CHAR_BIT*sizeof(unsigned))/2u; i>0u; i >>= 1u) {
hashid ^= (hashid>>i);
}
//
// the result here is always masked to the
// proper size after it is returned to the resource class
//
return hashid;
}
#endif // instantiateRecourceLib
//
// special resource table which uses
@@ -302,6 +267,7 @@ template <class ITEM>
class uintResTable : public resTable<ITEM, uintId> {
public:
uintResTable() : allocId(1u) {} // hashing is faster close to zero
virtual ~uintResTable();
inline void installItem(ITEM &item);
private:
@@ -316,6 +282,7 @@ class uintRes : public uintId, public tsSLNode<ITEM> {
friend class uintResTable<ITEM>;
public:
uintRes(unsigned idIn=UINT_MAX) : uintId(idIn) {}
virtual ~uintRes();
private:
//
// workaround for bug in DEC compiler
@@ -323,23 +290,6 @@ private:
void setId(unsigned newId) {this->id = newId;}
};
//
// uintRes<ITEM>::installItem()
//
// NOTE: This detects (and avoids) the case where
// the PV id wraps around and we attempt to have two
// resources with the same id.
//
template <class ITEM>
inline void uintResTable<ITEM>::installItem(ITEM &item)
{
int resTblStatus;
do {
item.uintRes<ITEM>::setId(allocId++);
resTblStatus = this->add(item);
}
while (resTblStatus);
}
//
// character string identifier
@@ -379,14 +329,7 @@ public:
pStr(typeIn==copyString?allocCopyString(idIn):idIn),
allocType(typeIn) {}
~ stringId()
{
if (this->allocType==copyString) {
if (this->pStr!=NULL) {
delete [] (char *) this->pStr;
}
}
}
virtual ~ stringId();
//
// The hash algorithm is a modification of the algorithm described in
@@ -428,54 +371,6 @@ private:
static const unsigned char stringIdFastHash[256];
};
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// stringId::resourceHash()
//
// The hash algorithm is a modification of the algorithm described in
// Fast Hashing of Variable Length Text Strings, Peter K. Pearson,
// Communications of the ACM, June 1990
// The modifications were designed by Marty Kraimer
//
resTableIndex stringId::resourceHash(unsigned nBitsId) const
{
if (this->pStr==NULL) {
return 0u;
}
unsigned h0 = 0u;
unsigned h1 = 0u;
unsigned c;
unsigned i;
for (i=0u; (c = this->pStr[i]); i++) {
//
// odd
//
if (i&1u) {
h1 = stringIdFastHash[h1 ^ c];
}
//
// even
//
else {
h0 = stringIdFastHash[h0 ^ c];
}
}
//
// does not work well for more than 65k entries ?
// (because some indexes in the table will not be produced)
//
if (nBitsId>=8u) {
h1 = h1 << (nBitsId-8u);
}
return h1 ^ h0;
}
#endif // instantiateRecourceLib
//
// resTable<T,ID>::init()
//
@@ -691,6 +586,165 @@ T *resTable<T,ID>::findDelete (tsSLList<T> &list, const ID &idIn)
return pItem;
}
//
// ~resTable<T,ID>::resTable()
//
template <class T, class ID>
resTable<T,ID>::~resTable()
{
if (this->pTable) {
this->destroyAllEntries();
assert (this->nInUse == 0u);
delete [] this->pTable;
}
}
//
// uintResTable<ITEM>::~uintResTable()
// (not inline because it is virtual)
//
template <class ITEM>
uintResTable<ITEM>::~uintResTable() {}
//
// uintRes<ITEM>::~uintRes()
// (not inline because it is virtual)
//
template <class ITEM>
uintRes<ITEM>::~uintRes() {}
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// uintId::resourceHash()
//
resTableIndex uintId::resourceHash(unsigned /* nBitsId */) const
{
resTableIndex hashid = this->id;
//
// This assumes worst case hash table index width of 1 bit.
// We will iterate this loop 5 times on a 32 bit architecture.
//
// A good optimizer will unroll this loop?
// Experiments using the microsoft compiler show that this isnt
// slower than switching on the architecture size and urolling the
// loop explicitly (that solution has resulted in portability
// problems in the past).
//
for (unsigned i=(CHAR_BIT*sizeof(unsigned))/2u; i>0u; i >>= 1u) {
hashid ^= (hashid>>i);
}
//
// the result here is always masked to the
// proper size after it is returned to the resource class
//
return hashid;
}
//
// uintResTable<ITEM>::~uintResTable()
// (not inline because it is virtual)
//
uintId::~uintId() {}
#endif // instantiateRecourceLib
//
// uintRes<ITEM>::installItem()
//
// NOTE: This detects (and avoids) the case where
// the PV id wraps around and we attempt to have two
// resources with the same id.
//
template <class ITEM>
inline void uintResTable<ITEM>::installItem(ITEM &item)
{
int resTblStatus;
do {
item.uintRes<ITEM>::setId(allocId++);
resTblStatus = this->add(item);
}
while (resTblStatus);
}
//
// stringId::~stringId()
//
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
stringId::~stringId()
{
if (this->allocType==copyString) {
if (this->pStr!=NULL) {
#ifdef _MSC_VER
//
// bugs in microsloth visual C++ appear to require
// a const cast away here
//
delete [] (char * const) this->pStr;
#else
delete [] this->pStr;
#endif
}
}
}
#endif // instantiateRecourceLib
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// stringId::resourceHash()
//
// The hash algorithm is a modification of the algorithm described in
// Fast Hashing of Variable Length Text Strings, Peter K. Pearson,
// Communications of the ACM, June 1990
// The modifications were designed by Marty Kraimer
//
resTableIndex stringId::resourceHash(unsigned nBitsId) const
{
if (this->pStr==NULL) {
return 0u;
}
unsigned h0 = 0u;
unsigned h1 = 0u;
unsigned c;
unsigned i;
for (i=0u; (c = this->pStr[i]); i++) {
//
// odd
//
if (i&1u) {
h1 = stringIdFastHash[h1 ^ c];
}
//
// even
//
else {
h0 = stringIdFastHash[h0 ^ c];
}
}
//
// does not work well for more than 65k entries ?
// (because some indexes in the table will not be produced)
//
if (nBitsId>=8u) {
h1 = h1 << (nBitsId-8u);
}
return h1 ^ h0;
}
#endif // instantiateRecourceLib
//
// this needs to be instanciated only once (normally in libCom)
//
@@ -719,6 +773,7 @@ const unsigned char stringId::stringIdFastHash[256] = {
111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238,
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47
};
#endif // instantiateRecourceLib
#endif // INCresourceLibh

View File

@@ -31,6 +31,9 @@
*
* History
* $Log$
* Revision 1.13 1998/06/16 03:01:44 jhill
* cosmetic
*
* Revision 1.12 1998/05/29 17:25:47 jhill
* allow use of epicsAssert.h
*
@@ -151,183 +154,46 @@ public:
// adds addList to the end of the list
// (and removes all items from addList)
//
void add (tsDLList<T> &addList)
{
//
// NOOP if addList is empty
//
if (addList.itemCount==0u) {
return;
}
if (this->itemCount==0u) {
//
// this is empty so just init from
// addList
//
*this = addList;
}
else {
tsDLNode<T> *pLastNode = this->pLast;
tsDLNode<T> *pAddListFirstNode = addList.pFirst;
//
// add addList to the end of this
//
pLastNode->pNext = addList.pFirst;
pAddListFirstNode->pPrev = addList.pLast;
this->pLast = addList.pLast;
this->itemCount += addList.itemCount;
}
//
// leave addList empty
//
addList.clear();
}
void add (tsDLList<T> &addList);
//
// add()
// (add an item to the end of the list)
//
void add (T &item)
{
tsDLNode<T> &node = item;
node.pNext = 0;
node.pPrev = this->pLast;
if (this->itemCount) {
tsDLNode<T> *pLastNode = this->pLast;
pLastNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->pLast = &item;
this->itemCount++;
}
void add (T &item);
//
// get ()
//
T * get()
{
T *pItem = this->pFirst;
if (pItem) {
this->remove (*pItem);
}
return pItem;
}
T * get();
//
// insertAfter()
// (place item in the list immediately after itemBefore)
//
void insertAfter (T &item, T &itemBefore)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeBefore = itemBefore;
node.pPrev = &itemBefore;
node.pNext = nodeBefore.pNext;
nodeBefore.pNext = &item;
if (node.pNext) {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->itemCount++;
}
void insertAfter (T &item, T &itemBefore);
//
// insertBefore ()
// (place item in the list immediately before itemAfter)
//
void insertBefore (T &item, T &itemAfter)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeAfter = itemAfter;
node.pNext = &itemAfter;
node.pPrev = nodeAfter.pPrev;
nodeAfter.pPrev = &item;
if (node.pPrev) {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->itemCount++;
}
void insertBefore (T &item, T &itemAfter);
//
// remove ()
//
void remove (T &item)
{
tsDLNode<T> &node = item;
if (this->pLast == &item) {
this->pLast = node.pPrev;
}
else {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = node.pPrev;
}
if (this->pFirst == &item) {
this->pFirst = node.pNext;
}
else {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = node.pNext;
}
this->itemCount--;
}
void remove (T &item);
//
// pop ()
// (returns the first item on the list)
T * pop()
{
return this->get();
}
T * pop();
//
// push ()
// (add an item at the beginning of the list)
//
void push (T &item)
{
tsDLNode<T> &node = item;
node.pPrev = 0;
node.pNext = this->pFirst;
if (this->itemCount) {
tsDLNode<T> *pFirstNode = this->pFirst;
pFirstNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->pFirst = &item;
this->itemCount++;
}
void push (T &item);
//
// find
@@ -364,6 +230,7 @@ private:
tsDLList (const tsDLList &);
};
//
// tsDLIterBD<T>
// (a bi-directional iterator in the style of the STL)
@@ -377,8 +244,7 @@ public:
tsDLIterBD (T *pInitialEntry) :
pEntry(pInitialEntry) {}
tsDLIterBD (class tsDLIterBD<T> &copyIn) :
pEntry(copyIn.pEntry) {}
tsDLIterBD (const class tsDLIterBD<T> &copyIn);
tsDLIterBD<T> & operator = (T *pNewEntry)
{
@@ -459,7 +325,7 @@ public:
private:
T *pEntry;
};
//
// tsDLIter<T>
//
@@ -474,7 +340,7 @@ private:
template <class T>
class tsDLIter {
public:
tsDLIter (const tsDLList<T> & listIn) :
tsDLIter (tsDLList<T> & listIn) :
pCurrent(0), pList(&listIn) {}
void reset ()
@@ -493,33 +359,9 @@ public:
this->reset(listIn);
}
T * next ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pFirst;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pNext;
}
this->pCurrent = pCur;
return pCur;
}
T * next ();
T * prev ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pLast;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pPrev;
}
this->pCurrent = pCur;
return pCur;
}
T * prev ();
T * first()
{
@@ -533,14 +375,11 @@ public:
return this->pCurrent;
}
T * operator () ()
{
return this->next();
}
T * operator () ();
protected:
T *pCurrent;
const tsDLList<T> *pList;
tsDLList<T> *pList;
};
//
@@ -561,30 +400,28 @@ protected:
template <class T>
class tsDLFwdIter: private tsDLIter<T> {
public:
tsDLFwdIter (const tsDLList<T> &listIn) :
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 ()
{
tsDLIter<T> &iterBase = *this;
return iterBase.next();
}
T * operator () ();
T * next ();
T * first()
{
tsDLIter<T> &iterBase = *this;
@@ -600,31 +437,7 @@ public:
// accessed sequentially even if an item
// is removed)
//
void remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// strip const (we didnt declare the
// list const in the constructor)
//
tsDLList<T> * pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the previous item
//
this->pCurrent = pCurNode->pPrev;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
void remove ();
};
//
@@ -645,29 +458,28 @@ public:
template <class T>
class tsDLBwdIter : private tsDLIter<T> {
public:
tsDLBwdIter(const tsDLList<T> &listIn) :
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 * operator () ();
T * prev ();
T * last()
{
return this->tsDLIter<T>::last();
@@ -683,43 +495,366 @@ public:
// accessed sequentially even if an item
// is removed)
//
void remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// strip const (we didnt declare the
// list const in the constructor)
//
tsDLList<T> * pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the item after the
// item being deleted
//
this->pCurrent = pCurNode->pNext;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
void remove ();
};
//
// MS Visual C 6.0 requires that this code is not provided in
// the class definition because the class isnt fully defined yet
//
template <class T>
inline tsDLIterBD<T>::tsDLIterBD(const class tsDLIterBD<T> &copyIn) :
pEntry(copyIn.pEntry) {}
//
// find
// tsDLList<T>::remove ()
//
template <class T>
void tsDLList<T>::remove (T &item)
{
tsDLNode<T> &node = item;
if (this->pLast == &item) {
this->pLast = node.pPrev;
}
else {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = node.pPrev;
}
if (this->pFirst == &item) {
this->pFirst = node.pNext;
}
else {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = node.pNext;
}
this->itemCount--;
}
//
// tsDLList<T>::get ()
//
template <class T>
inline T * tsDLList<T>::get()
{
T *pItem = this->pFirst;
if (pItem) {
this->remove (*pItem);
}
return pItem;
}
//
// tsDLList<T>::pop ()
// (returns the first item on the list)
template <class T>
inline T * tsDLList<T>::pop()
{
return this->get();
}
//
// add() -
// adds addList to the end of the list
// (and removes all items from addList)
//
template <class T>
void tsDLList<T>::add (tsDLList<T> &addList)
{
//
// NOOP if addList is empty
//
if (addList.itemCount==0u) {
return;
}
if (this->itemCount==0u) {
//
// this is empty so just init from
// addList
//
*this = addList;
}
else {
tsDLNode<T> *pLastNode = this->pLast;
tsDLNode<T> *pAddListFirstNode = addList.pFirst;
//
// add addList to the end of this
//
pLastNode->pNext = addList.pFirst;
pAddListFirstNode->pPrev = addList.pLast;
this->pLast = addList.pLast;
this->itemCount += addList.itemCount;
}
//
// leave addList empty
//
addList.clear();
}
//
// add()
// (add an item to the end of the list)
//
template <class T>
void tsDLList<T>::add (T &item)
{
tsDLNode<T> &node = item;
node.pNext = 0;
node.pPrev = this->pLast;
if (this->itemCount) {
tsDLNode<T> *pLastNode = this->pLast;
pLastNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->pLast = &item;
this->itemCount++;
}
//
// insertAfter()
// (place item in the list immediately after itemBefore)
//
template <class T>
void tsDLList<T>::insertAfter (T &item, T &itemBefore)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeBefore = itemBefore;
node.pPrev = &itemBefore;
node.pNext = nodeBefore.pNext;
nodeBefore.pNext = &item;
if (node.pNext) {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->itemCount++;
}
//
// insertBefore ()
// (place item in the list immediately before itemAfter)
//
template <class T>
void tsDLList<T>::insertBefore (T &item, T &itemAfter)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeAfter = itemAfter;
node.pNext = &itemAfter;
node.pPrev = nodeAfter.pPrev;
nodeAfter.pPrev = &item;
if (node.pPrev) {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->itemCount++;
}
//
// push ()
// (add an item at the beginning of the list)
//
template <class T>
void tsDLList<T>::push (T &item)
{
tsDLNode<T> &node = item;
node.pPrev = 0;
node.pNext = this->pFirst;
if (this->itemCount) {
tsDLNode<T> *pFirstNode = this->pFirst;
pFirstNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->pFirst = &item;
this->itemCount++;
}
//
// tsDLIter<T>::next ()
//
template <class T>
T * tsDLIter<T>::next ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pFirst;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pNext;
}
this->pCurrent = pCur;
return pCur;
}
//
// tsDLIter<T>::prev ()
//
template <class T>
T * tsDLIter<T>::prev ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pLast;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pPrev;
}
this->pCurrent = pCur;
return pCur;
}
//
// tsDLIter<T>::operator () ()
//
template <class T>
inline T * tsDLIter<T>::operator () ()
{
return this->next();
}
//
// 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)
//
template <class T>
void tsDLBwdIter<T>::remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// strip const (we didnt declare the
// list const in the constructor)
//
tsDLList<T> * pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the item after the
// item being deleted
//
this->pCurrent = pCurNode->pNext;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
//
// tsDLBwdIter<T>::operator () ()
//
template <class T>
inline T * tsDLBwdIter<T>::operator () ()
{
return this->tsDLIter<T>::prev();
}
//
// tsDLBwdIter<T>::prev ()
//
template <class T>
inline T * tsDLBwdIter<T>::prev ()
{
return this->tsDLIter<T>::prev();
}
//
// tsDLFwdIter<T>::remove ()
// (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)
//
template <class T>
void tsDLFwdIter<T>::remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// Move this->pCurrent to the previous item
//
this->pCurrent = pCurNode->pPrev;
//
// delete current item
//
this->pList->remove(*pCur);
}
}
//
// tsDLFwdIter<T>::next ()
//
template <class T>
inline T * tsDLFwdIter<T>::next ()
{
tsDLIter<T> &iterBase = *this;
return iterBase.next();
}
//
// tsDLFwdIter<T>::operator () ()
//
template <class T>
inline T * tsDLFwdIter<T>::operator () ()
{
return this->next();
}
//
// tsDLList<T>::find ()
// returns -1 if the item isnt on the list
// and the node number (beginning with zero if
// it is)
//
template <class T>
inline int tsDLList<T>::find(T &item) const
int tsDLList<T>::find(T &item) const
{
tsDLFwdIter<T> iter(*this);
tsDLNode<T> *pItem;

View File

@@ -31,6 +31,9 @@
*
* History
* $Log$
* Revision 1.12 1998/06/16 03:03:07 jhill
* eliminated dangling ptr warning from bounds checker
*
* Revision 1.11 1998/05/05 18:06:58 jhill
* rearranged to allow compilation by g++ 2.8.1
*
@@ -183,22 +186,7 @@ public:
// (intel) dont like to cast a NULL pointer from a tsSLNode<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
T * next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
}
return this->pCurrent;
}
T * next ();
//
// move iterator forward
@@ -245,24 +233,7 @@ public:
// (intel) dont like to cast a NULL pointer from a tsSLNode<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
T * next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pPrevious = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
this->pPrevious = 0;
}
return this->pCurrent;
}
T * next ();
//
// move iterator forward
@@ -284,29 +255,7 @@ public:
// the iterator to the next item. If there is
// no current item this function assert fails.
//
void remove ()
{
assert (this->pCurrent!=0);
tsSLNode<T> *pPrevNode;
tsSLNode<T> *pCurNode = this->pCurrent;
if (this->pPrevious==0) {
pPrevNode = &this->list;
//
// this assert fails if it is an attempt to
// delete twice without moving the iterator
//
assert (pPrevNode->pNext == this->pCurrent);
}
else {
pPrevNode = this->pPrevious;
}
pPrevNode->pNext = pCurNode->pNext;
this->pCurrent = this->pPrevious;
this->pPrevious = 0;
}
void remove ();
private:
T *pPrevious;
@@ -314,3 +263,97 @@ private:
tsSLList<T> &list;
};
//
// tsSLIter<T>::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<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
template <class T>
T * tsSLIter<T>::next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
}
return this->pCurrent;
}
//
// tsSLIterRm<T>::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<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
template <class T>
T * tsSLIterRm<T>::next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pPrevious = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
this->pPrevious = 0;
}
return this->pCurrent;
}
//
// tsSLIterRm<T>::remove ()
//
// 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)
//
// This cant be called twice in a row without moving
// the iterator to the next item. If there is
// no current item this function assert fails.
//
template <class T>
void tsSLIterRm<T>::remove ()
{
assert (this->pCurrent!=0);
tsSLNode<T> *pPrevNode;
tsSLNode<T> *pCurNode = this->pCurrent;
if (this->pPrevious==0) {
pPrevNode = &this->list;
//
// this assert fails if it is an attempt to
// delete twice without moving the iterator
//
assert (pPrevNode->pNext == this->pCurrent);
}
else {
pPrevNode = this->pPrevious;
}
pPrevNode->pNext = pCurNode->pNext;
this->pCurrent = this->pPrevious;
this->pPrevious = 0;
}

View File

@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.17 1998/06/16 03:00:19 jhill
* cleaned up fast string hash table
*
* Revision 1.16 1998/04/10 23:07:33 jhill
* fixed solaris architecture specific problem where xxx>>32 was ignored
*
@@ -129,14 +132,7 @@ public:
int init(unsigned nHashTableEntries);
~resTable()
{
if (this->pTable) {
this->destroyAllEntries();
assert (this->nInUse == 0u);
delete [] this->pTable;
}
}
virtual ~resTable();
//
// destroy all res in the table
@@ -240,6 +236,7 @@ private:
class epicsShareClass uintId {
public:
uintId (unsigned idIn=UINT_MAX) : id(idIn) {}
virtual ~uintId();
int operator == (const uintId &idIn)
{
@@ -259,38 +256,6 @@ protected:
unsigned id;
};
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// uintId::resourceHash()
//
resTableIndex uintId::resourceHash(unsigned /* nBitsId */) const
{
resTableIndex hashid = this->id;
//
// This assumes worst case hash table index width of 1 bit.
// We will iterate this loop 5 times on a 32 bit architecture.
//
// A good optimizer will unroll this loop?
// Experiments using the microsoft compiler show that this isnt
// slower than switching on the architecture size and urolling the
// loop explicitly (that solution has resulted in portability
// problems in the past).
//
for (unsigned i=(CHAR_BIT*sizeof(unsigned))/2u; i>0u; i >>= 1u) {
hashid ^= (hashid>>i);
}
//
// the result here is always masked to the
// proper size after it is returned to the resource class
//
return hashid;
}
#endif // instantiateRecourceLib
//
// special resource table which uses
@@ -302,6 +267,7 @@ template <class ITEM>
class uintResTable : public resTable<ITEM, uintId> {
public:
uintResTable() : allocId(1u) {} // hashing is faster close to zero
virtual ~uintResTable();
inline void installItem(ITEM &item);
private:
@@ -316,6 +282,7 @@ class uintRes : public uintId, public tsSLNode<ITEM> {
friend class uintResTable<ITEM>;
public:
uintRes(unsigned idIn=UINT_MAX) : uintId(idIn) {}
virtual ~uintRes();
private:
//
// workaround for bug in DEC compiler
@@ -323,23 +290,6 @@ private:
void setId(unsigned newId) {this->id = newId;}
};
//
// uintRes<ITEM>::installItem()
//
// NOTE: This detects (and avoids) the case where
// the PV id wraps around and we attempt to have two
// resources with the same id.
//
template <class ITEM>
inline void uintResTable<ITEM>::installItem(ITEM &item)
{
int resTblStatus;
do {
item.uintRes<ITEM>::setId(allocId++);
resTblStatus = this->add(item);
}
while (resTblStatus);
}
//
// character string identifier
@@ -379,14 +329,7 @@ public:
pStr(typeIn==copyString?allocCopyString(idIn):idIn),
allocType(typeIn) {}
~ stringId()
{
if (this->allocType==copyString) {
if (this->pStr!=NULL) {
delete [] (char *) this->pStr;
}
}
}
virtual ~ stringId();
//
// The hash algorithm is a modification of the algorithm described in
@@ -428,54 +371,6 @@ private:
static const unsigned char stringIdFastHash[256];
};
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// stringId::resourceHash()
//
// The hash algorithm is a modification of the algorithm described in
// Fast Hashing of Variable Length Text Strings, Peter K. Pearson,
// Communications of the ACM, June 1990
// The modifications were designed by Marty Kraimer
//
resTableIndex stringId::resourceHash(unsigned nBitsId) const
{
if (this->pStr==NULL) {
return 0u;
}
unsigned h0 = 0u;
unsigned h1 = 0u;
unsigned c;
unsigned i;
for (i=0u; (c = this->pStr[i]); i++) {
//
// odd
//
if (i&1u) {
h1 = stringIdFastHash[h1 ^ c];
}
//
// even
//
else {
h0 = stringIdFastHash[h0 ^ c];
}
}
//
// does not work well for more than 65k entries ?
// (because some indexes in the table will not be produced)
//
if (nBitsId>=8u) {
h1 = h1 << (nBitsId-8u);
}
return h1 ^ h0;
}
#endif // instantiateRecourceLib
//
// resTable<T,ID>::init()
//
@@ -691,6 +586,165 @@ T *resTable<T,ID>::findDelete (tsSLList<T> &list, const ID &idIn)
return pItem;
}
//
// ~resTable<T,ID>::resTable()
//
template <class T, class ID>
resTable<T,ID>::~resTable()
{
if (this->pTable) {
this->destroyAllEntries();
assert (this->nInUse == 0u);
delete [] this->pTable;
}
}
//
// uintResTable<ITEM>::~uintResTable()
// (not inline because it is virtual)
//
template <class ITEM>
uintResTable<ITEM>::~uintResTable() {}
//
// uintRes<ITEM>::~uintRes()
// (not inline because it is virtual)
//
template <class ITEM>
uintRes<ITEM>::~uintRes() {}
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// uintId::resourceHash()
//
resTableIndex uintId::resourceHash(unsigned /* nBitsId */) const
{
resTableIndex hashid = this->id;
//
// This assumes worst case hash table index width of 1 bit.
// We will iterate this loop 5 times on a 32 bit architecture.
//
// A good optimizer will unroll this loop?
// Experiments using the microsoft compiler show that this isnt
// slower than switching on the architecture size and urolling the
// loop explicitly (that solution has resulted in portability
// problems in the past).
//
for (unsigned i=(CHAR_BIT*sizeof(unsigned))/2u; i>0u; i >>= 1u) {
hashid ^= (hashid>>i);
}
//
// the result here is always masked to the
// proper size after it is returned to the resource class
//
return hashid;
}
//
// uintResTable<ITEM>::~uintResTable()
// (not inline because it is virtual)
//
uintId::~uintId() {}
#endif // instantiateRecourceLib
//
// uintRes<ITEM>::installItem()
//
// NOTE: This detects (and avoids) the case where
// the PV id wraps around and we attempt to have two
// resources with the same id.
//
template <class ITEM>
inline void uintResTable<ITEM>::installItem(ITEM &item)
{
int resTblStatus;
do {
item.uintRes<ITEM>::setId(allocId++);
resTblStatus = this->add(item);
}
while (resTblStatus);
}
//
// stringId::~stringId()
//
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
stringId::~stringId()
{
if (this->allocType==copyString) {
if (this->pStr!=NULL) {
#ifdef _MSC_VER
//
// bugs in microsloth visual C++ appear to require
// a const cast away here
//
delete [] (char * const) this->pStr;
#else
delete [] this->pStr;
#endif
}
}
}
#endif // instantiateRecourceLib
//
// this needs to be instanciated only once (normally in libCom)
//
#ifdef instantiateRecourceLib
//
// stringId::resourceHash()
//
// The hash algorithm is a modification of the algorithm described in
// Fast Hashing of Variable Length Text Strings, Peter K. Pearson,
// Communications of the ACM, June 1990
// The modifications were designed by Marty Kraimer
//
resTableIndex stringId::resourceHash(unsigned nBitsId) const
{
if (this->pStr==NULL) {
return 0u;
}
unsigned h0 = 0u;
unsigned h1 = 0u;
unsigned c;
unsigned i;
for (i=0u; (c = this->pStr[i]); i++) {
//
// odd
//
if (i&1u) {
h1 = stringIdFastHash[h1 ^ c];
}
//
// even
//
else {
h0 = stringIdFastHash[h0 ^ c];
}
}
//
// does not work well for more than 65k entries ?
// (because some indexes in the table will not be produced)
//
if (nBitsId>=8u) {
h1 = h1 << (nBitsId-8u);
}
return h1 ^ h0;
}
#endif // instantiateRecourceLib
//
// this needs to be instanciated only once (normally in libCom)
//
@@ -719,6 +773,7 @@ const unsigned char stringId::stringIdFastHash[256] = {
111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238,
134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47
};
#endif // instantiateRecourceLib
#endif // INCresourceLibh

View File

@@ -31,6 +31,9 @@
*
* History
* $Log$
* Revision 1.13 1998/06/16 03:01:44 jhill
* cosmetic
*
* Revision 1.12 1998/05/29 17:25:47 jhill
* allow use of epicsAssert.h
*
@@ -151,183 +154,46 @@ public:
// adds addList to the end of the list
// (and removes all items from addList)
//
void add (tsDLList<T> &addList)
{
//
// NOOP if addList is empty
//
if (addList.itemCount==0u) {
return;
}
if (this->itemCount==0u) {
//
// this is empty so just init from
// addList
//
*this = addList;
}
else {
tsDLNode<T> *pLastNode = this->pLast;
tsDLNode<T> *pAddListFirstNode = addList.pFirst;
//
// add addList to the end of this
//
pLastNode->pNext = addList.pFirst;
pAddListFirstNode->pPrev = addList.pLast;
this->pLast = addList.pLast;
this->itemCount += addList.itemCount;
}
//
// leave addList empty
//
addList.clear();
}
void add (tsDLList<T> &addList);
//
// add()
// (add an item to the end of the list)
//
void add (T &item)
{
tsDLNode<T> &node = item;
node.pNext = 0;
node.pPrev = this->pLast;
if (this->itemCount) {
tsDLNode<T> *pLastNode = this->pLast;
pLastNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->pLast = &item;
this->itemCount++;
}
void add (T &item);
//
// get ()
//
T * get()
{
T *pItem = this->pFirst;
if (pItem) {
this->remove (*pItem);
}
return pItem;
}
T * get();
//
// insertAfter()
// (place item in the list immediately after itemBefore)
//
void insertAfter (T &item, T &itemBefore)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeBefore = itemBefore;
node.pPrev = &itemBefore;
node.pNext = nodeBefore.pNext;
nodeBefore.pNext = &item;
if (node.pNext) {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->itemCount++;
}
void insertAfter (T &item, T &itemBefore);
//
// insertBefore ()
// (place item in the list immediately before itemAfter)
//
void insertBefore (T &item, T &itemAfter)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeAfter = itemAfter;
node.pNext = &itemAfter;
node.pPrev = nodeAfter.pPrev;
nodeAfter.pPrev = &item;
if (node.pPrev) {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->itemCount++;
}
void insertBefore (T &item, T &itemAfter);
//
// remove ()
//
void remove (T &item)
{
tsDLNode<T> &node = item;
if (this->pLast == &item) {
this->pLast = node.pPrev;
}
else {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = node.pPrev;
}
if (this->pFirst == &item) {
this->pFirst = node.pNext;
}
else {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = node.pNext;
}
this->itemCount--;
}
void remove (T &item);
//
// pop ()
// (returns the first item on the list)
T * pop()
{
return this->get();
}
T * pop();
//
// push ()
// (add an item at the beginning of the list)
//
void push (T &item)
{
tsDLNode<T> &node = item;
node.pPrev = 0;
node.pNext = this->pFirst;
if (this->itemCount) {
tsDLNode<T> *pFirstNode = this->pFirst;
pFirstNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->pFirst = &item;
this->itemCount++;
}
void push (T &item);
//
// find
@@ -364,6 +230,7 @@ private:
tsDLList (const tsDLList &);
};
//
// tsDLIterBD<T>
// (a bi-directional iterator in the style of the STL)
@@ -377,8 +244,7 @@ public:
tsDLIterBD (T *pInitialEntry) :
pEntry(pInitialEntry) {}
tsDLIterBD (class tsDLIterBD<T> &copyIn) :
pEntry(copyIn.pEntry) {}
tsDLIterBD (const class tsDLIterBD<T> &copyIn);
tsDLIterBD<T> & operator = (T *pNewEntry)
{
@@ -459,7 +325,7 @@ public:
private:
T *pEntry;
};
//
// tsDLIter<T>
//
@@ -474,7 +340,7 @@ private:
template <class T>
class tsDLIter {
public:
tsDLIter (const tsDLList<T> & listIn) :
tsDLIter (tsDLList<T> & listIn) :
pCurrent(0), pList(&listIn) {}
void reset ()
@@ -493,33 +359,9 @@ public:
this->reset(listIn);
}
T * next ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pFirst;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pNext;
}
this->pCurrent = pCur;
return pCur;
}
T * next ();
T * prev ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pLast;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pPrev;
}
this->pCurrent = pCur;
return pCur;
}
T * prev ();
T * first()
{
@@ -533,14 +375,11 @@ public:
return this->pCurrent;
}
T * operator () ()
{
return this->next();
}
T * operator () ();
protected:
T *pCurrent;
const tsDLList<T> *pList;
tsDLList<T> *pList;
};
//
@@ -561,30 +400,28 @@ protected:
template <class T>
class tsDLFwdIter: private tsDLIter<T> {
public:
tsDLFwdIter (const tsDLList<T> &listIn) :
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 ()
{
tsDLIter<T> &iterBase = *this;
return iterBase.next();
}
T * operator () ();
T * next ();
T * first()
{
tsDLIter<T> &iterBase = *this;
@@ -600,31 +437,7 @@ public:
// accessed sequentially even if an item
// is removed)
//
void remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// strip const (we didnt declare the
// list const in the constructor)
//
tsDLList<T> * pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the previous item
//
this->pCurrent = pCurNode->pPrev;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
void remove ();
};
//
@@ -645,29 +458,28 @@ public:
template <class T>
class tsDLBwdIter : private tsDLIter<T> {
public:
tsDLBwdIter(const tsDLList<T> &listIn) :
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 * operator () ();
T * prev ();
T * last()
{
return this->tsDLIter<T>::last();
@@ -683,43 +495,366 @@ public:
// accessed sequentially even if an item
// is removed)
//
void remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// strip const (we didnt declare the
// list const in the constructor)
//
tsDLList<T> * pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the item after the
// item being deleted
//
this->pCurrent = pCurNode->pNext;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
void remove ();
};
//
// MS Visual C 6.0 requires that this code is not provided in
// the class definition because the class isnt fully defined yet
//
template <class T>
inline tsDLIterBD<T>::tsDLIterBD(const class tsDLIterBD<T> &copyIn) :
pEntry(copyIn.pEntry) {}
//
// find
// tsDLList<T>::remove ()
//
template <class T>
void tsDLList<T>::remove (T &item)
{
tsDLNode<T> &node = item;
if (this->pLast == &item) {
this->pLast = node.pPrev;
}
else {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = node.pPrev;
}
if (this->pFirst == &item) {
this->pFirst = node.pNext;
}
else {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = node.pNext;
}
this->itemCount--;
}
//
// tsDLList<T>::get ()
//
template <class T>
inline T * tsDLList<T>::get()
{
T *pItem = this->pFirst;
if (pItem) {
this->remove (*pItem);
}
return pItem;
}
//
// tsDLList<T>::pop ()
// (returns the first item on the list)
template <class T>
inline T * tsDLList<T>::pop()
{
return this->get();
}
//
// add() -
// adds addList to the end of the list
// (and removes all items from addList)
//
template <class T>
void tsDLList<T>::add (tsDLList<T> &addList)
{
//
// NOOP if addList is empty
//
if (addList.itemCount==0u) {
return;
}
if (this->itemCount==0u) {
//
// this is empty so just init from
// addList
//
*this = addList;
}
else {
tsDLNode<T> *pLastNode = this->pLast;
tsDLNode<T> *pAddListFirstNode = addList.pFirst;
//
// add addList to the end of this
//
pLastNode->pNext = addList.pFirst;
pAddListFirstNode->pPrev = addList.pLast;
this->pLast = addList.pLast;
this->itemCount += addList.itemCount;
}
//
// leave addList empty
//
addList.clear();
}
//
// add()
// (add an item to the end of the list)
//
template <class T>
void tsDLList<T>::add (T &item)
{
tsDLNode<T> &node = item;
node.pNext = 0;
node.pPrev = this->pLast;
if (this->itemCount) {
tsDLNode<T> *pLastNode = this->pLast;
pLastNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->pLast = &item;
this->itemCount++;
}
//
// insertAfter()
// (place item in the list immediately after itemBefore)
//
template <class T>
void tsDLList<T>::insertAfter (T &item, T &itemBefore)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeBefore = itemBefore;
node.pPrev = &itemBefore;
node.pNext = nodeBefore.pNext;
nodeBefore.pNext = &item;
if (node.pNext) {
tsDLNode<T> *pNextNode = node.pNext;
pNextNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->itemCount++;
}
//
// insertBefore ()
// (place item in the list immediately before itemAfter)
//
template <class T>
void tsDLList<T>::insertBefore (T &item, T &itemAfter)
{
tsDLNode<T> &node = item;
tsDLNode<T> &nodeAfter = itemAfter;
node.pNext = &itemAfter;
node.pPrev = nodeAfter.pPrev;
nodeAfter.pPrev = &item;
if (node.pPrev) {
tsDLNode<T> *pPrevNode = node.pPrev;
pPrevNode->pNext = &item;
}
else {
this->pFirst = &item;
}
this->itemCount++;
}
//
// push ()
// (add an item at the beginning of the list)
//
template <class T>
void tsDLList<T>::push (T &item)
{
tsDLNode<T> &node = item;
node.pPrev = 0;
node.pNext = this->pFirst;
if (this->itemCount) {
tsDLNode<T> *pFirstNode = this->pFirst;
pFirstNode->pPrev = &item;
}
else {
this->pLast = &item;
}
this->pFirst = &item;
this->itemCount++;
}
//
// tsDLIter<T>::next ()
//
template <class T>
T * tsDLIter<T>::next ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pFirst;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pNext;
}
this->pCurrent = pCur;
return pCur;
}
//
// tsDLIter<T>::prev ()
//
template <class T>
T * tsDLIter<T>::prev ()
{
T *pCur = this->pCurrent;
if (pCur==0) {
pCur = this->pList->pLast;
}
else {
tsDLNode<T> *pCurNode = pCur;
pCur = pCurNode->pPrev;
}
this->pCurrent = pCur;
return pCur;
}
//
// tsDLIter<T>::operator () ()
//
template <class T>
inline T * tsDLIter<T>::operator () ()
{
return this->next();
}
//
// 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)
//
template <class T>
void tsDLBwdIter<T>::remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// strip const (we didnt declare the
// list const in the constructor)
//
tsDLList<T> * pMutableList =
(tsDLList<T> *) this->pList;
//
// Move this->pCurrent to the item after the
// item being deleted
//
this->pCurrent = pCurNode->pNext;
//
// delete current item
//
pMutableList->remove(*pCur);
}
}
//
// tsDLBwdIter<T>::operator () ()
//
template <class T>
inline T * tsDLBwdIter<T>::operator () ()
{
return this->tsDLIter<T>::prev();
}
//
// tsDLBwdIter<T>::prev ()
//
template <class T>
inline T * tsDLBwdIter<T>::prev ()
{
return this->tsDLIter<T>::prev();
}
//
// tsDLFwdIter<T>::remove ()
// (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)
//
template <class T>
void tsDLFwdIter<T>::remove ()
{
T *pCur = this->pCurrent;
if (pCur) {
tsDLNode<T> *pCurNode = pCur;
//
// Move this->pCurrent to the previous item
//
this->pCurrent = pCurNode->pPrev;
//
// delete current item
//
this->pList->remove(*pCur);
}
}
//
// tsDLFwdIter<T>::next ()
//
template <class T>
inline T * tsDLFwdIter<T>::next ()
{
tsDLIter<T> &iterBase = *this;
return iterBase.next();
}
//
// tsDLFwdIter<T>::operator () ()
//
template <class T>
inline T * tsDLFwdIter<T>::operator () ()
{
return this->next();
}
//
// tsDLList<T>::find ()
// returns -1 if the item isnt on the list
// and the node number (beginning with zero if
// it is)
//
template <class T>
inline int tsDLList<T>::find(T &item) const
int tsDLList<T>::find(T &item) const
{
tsDLFwdIter<T> iter(*this);
tsDLNode<T> *pItem;

View File

@@ -31,6 +31,9 @@
*
* History
* $Log$
* Revision 1.12 1998/06/16 03:03:07 jhill
* eliminated dangling ptr warning from bounds checker
*
* Revision 1.11 1998/05/05 18:06:58 jhill
* rearranged to allow compilation by g++ 2.8.1
*
@@ -183,22 +186,7 @@ public:
// (intel) dont like to cast a NULL pointer from a tsSLNode<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
T * next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
}
return this->pCurrent;
}
T * next ();
//
// move iterator forward
@@ -245,24 +233,7 @@ public:
// (intel) dont like to cast a NULL pointer from a tsSLNode<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
T * next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pPrevious = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
this->pPrevious = 0;
}
return this->pCurrent;
}
T * next ();
//
// move iterator forward
@@ -284,29 +255,7 @@ public:
// the iterator to the next item. If there is
// no current item this function assert fails.
//
void remove ()
{
assert (this->pCurrent!=0);
tsSLNode<T> *pPrevNode;
tsSLNode<T> *pCurNode = this->pCurrent;
if (this->pPrevious==0) {
pPrevNode = &this->list;
//
// this assert fails if it is an attempt to
// delete twice without moving the iterator
//
assert (pPrevNode->pNext == this->pCurrent);
}
else {
pPrevNode = this->pPrevious;
}
pPrevNode->pNext = pCurNode->pNext;
this->pCurrent = this->pPrevious;
this->pPrevious = 0;
}
void remove ();
private:
T *pPrevious;
@@ -314,3 +263,97 @@ private:
tsSLList<T> &list;
};
//
// tsSLIter<T>::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<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
template <class T>
T * tsSLIter<T>::next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
}
return this->pCurrent;
}
//
// tsSLIterRm<T>::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<T> to a T even if
// tsSLNode<T> is always a base class of a T.
//
template <class T>
T * tsSLIterRm<T>::next ()
{
if (this->pCurrent!=0) {
tsSLNode<T> *pCurNode = this->pCurrent;
this->pPrevious = this->pCurrent;
this->pCurrent = pCurNode->pNext;
}
else {
const tsSLNode<T> &first = this->list;
//
// assume that we are starting (or restarting) at the
// beginning of the list
//
this->pCurrent = first.pNext;
this->pPrevious = 0;
}
return this->pCurrent;
}
//
// tsSLIterRm<T>::remove ()
//
// 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)
//
// This cant be called twice in a row without moving
// the iterator to the next item. If there is
// no current item this function assert fails.
//
template <class T>
void tsSLIterRm<T>::remove ()
{
assert (this->pCurrent!=0);
tsSLNode<T> *pPrevNode;
tsSLNode<T> *pCurNode = this->pCurrent;
if (this->pPrevious==0) {
pPrevNode = &this->list;
//
// this assert fails if it is an attempt to
// delete twice without moving the iterator
//
assert (pPrevNode->pNext == this->pCurrent);
}
else {
pPrevNode = this->pPrevious;
}
pPrevNode->pNext = pCurNode->pNext;
this->pCurrent = this->pPrevious;
this->pPrevious = 0;
}