home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
SLBASE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
11KB
|
401 lines
/****************************************************************************
$Id: slbase.cpp 501.0 1995/03/07 12:26:20 RON Exp $
Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
Project: Tarma Library for C++ V5.0
Author: Ron van der Wal
Implementation of class TLSLBase.
$Log: slbase.cpp $
Revision 501.0 1995/03/07 12:26:20 RON
Updated for TLX 5.01
Revision 1.7 1995/01/31 16:30:24 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.6 1995/01/06 15:58:17 ron
Corrected Revision keyword
Revision 1.5 1994/11/16 15:42:53 ron
Added module info; rearranged #include directives
Revision 1.4 1994/09/28 14:21:31 ron
Removed Macintosh-style #include references
Revision 1.3 1994/09/27 20:22:56 ron
Changed path separator from / to \
Revision 1.2 1994/09/26 15:47:15 ron
Changed include file references
Revision 1.1 1994/08/16 18:13:12 ron
Initial revision
****************************************************************************/
#include <tlx\501\_build.h>
TLX_MODULE_INFO("$Revision: 501.0 $");
#include <tlx\501\except.h> // Exception handling
#include <tlx\501\slists.h> // Class declaration
/*-------------------------------------------------------------------------*/
TLSLBase::TLSLBase(bool aOwner)
/* Constructor, also doubles as default constructor. Creates an empty list.
---------------------------------------------------------------------------*/
: mHead(0), mTail(0), mCount(0), mOwner(aOwner)
{
}
/*-------------------------------------------------------------------------*/
TLSLBase::TLSLBase(const TLSLBase &)
/* Copy constructor, does not copy the other list.
---------------------------------------------------------------------------*/
: mHead(0), mTail(0), mCount(0), mOwner(false)
{
}
/*-------------------------------------------------------------------------*/
TLSLBase::~TLSLBase()
/* Destructor. If the list is woner of its elements at the time of
destruction, it deletes all its elements.
---------------------------------------------------------------------------*/
{
if (mOwner) CleanUp();
}
/*-------------------------------------------------------------------------*/
void TLSLBase::Append(TLSLink *aLink)
/* Adds an element at the end of the list. The element pointer must be
nonzero, and the element must not currently be part of a list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT_NULL(aLink->mNext);
if (mTail)
mTail->Append(aLink);
else
mHead = aLink;
mTail = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
void TLSLBase::Append(TLSLink *aLink, TLSLink *aPos)
/* Inserts a link after another link in the list. The link to insert
must not currently be part of a list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT_PTR(aPos);
TLX_ASSERT_NULL(aLink->mNext);
TLX_ASSERT(Contains(aPos));
aPos->Append(aLink);
if (aPos == mTail)
mTail = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
bool TLSLBase::BecomeOwner(bool aOwner)
/* Changes the owner status, returning the previous status.
---------------------------------------------------------------------------*/
{
bool oldstat = mOwner;
mOwner = aOwner;
return oldstat;
}
/*-------------------------------------------------------------------------*/
void TLSLBase::CleanUp()
/* Deletes all elements in the list. The list should be owner for this
function to be called.
---------------------------------------------------------------------------*/
{
TLX_ASSERT(mOwner);
TLSLink *rover = mHead;
while (rover)
{
TLSLink *tmp = rover;
rover = rover->Next();
tmp->Unlink();
delete tmp;
}
}
/*-------------------------------------------------------------------------*/
void TLSLBase::Concat(TLSLink *aList)
/* Appends another list to the current one. This function differs from
Append() in that Append() assumes the addition of a single element.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aList);
if (mTail)
mTail->Append(aList);
else
mHead = aList;
// Find end of new list, counting additional elements as we go
mTail = aList;
while (mTail)
{
++mCount;
mTail = mTail->mNext;
}
}
/*-------------------------------------------------------------------------*/
void TLSLBase::Concat(TLSLBase &aList)
/* Takes over another list in its entirety. The new list is added at the
end of the current list; the original list is then made empty.
---------------------------------------------------------------------------*/
{
TLX_ASSERT(this != &aList);
TLX_ASSERT(aList.mCount > 0 || (aList.mHead == 0 && aList.mTail == 0));
if (aList.mHead)
{
Concat(aList.mHead);
aList.mHead =
aList.mTail = 0;
aList.mCount = 0;
}
}
/*-------------------------------------------------------------------------*/
bool TLSLBase::Contains(TLSLink *aLink) const
/* Tests whether a given element appears in the list. The function performs
a linear search.
---------------------------------------------------------------------------*/
{
if (!aLink) return false;
for (TLSLink *rover = mHead; rover; rover = rover->Next())
if (rover == aLink)
return true;
return false;
}
/*-------------------------------------------------------------------------*/
TLSLink *TLSLBase::Extract(TLSLink *aLink)
/* Removes and returns a specific link from the list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT(Contains(aLink));
if (aLink == mTail)
{
TLX_ASSERT_NULL(aLink->Next());
if (aLink == mHead) // Single element list
mTail = 0;
else
{
// Find the link preceding the one now being removed
TLSLink *rover;
for (rover = mHead; rover && rover->Next() != aLink;
rover = rover->Next())
;
if (rover)
{
TLX_ASSERT(rover->Next() == aLink);
mTail = rover;
}
}
}
if (aLink == mHead)
mHead = aLink->Next();
aLink->Unlink();
TLX_ASSERT(mCount > 0);
mCount--;
return aLink;
}
/*-------------------------------------------------------------------------*/
TLSLink *TLSLBase::ExtractHead()
/* Removes and returns the first element of the list.
---------------------------------------------------------------------------*/
{
if (IsEmpty())
THROW(TLXEmpty(LOCUS));
TLX_ASSERT_PTR(mHead);
return Extract(mHead);
}
/*-------------------------------------------------------------------------*/
TLSLink *TLSLBase::ExtractTail()
/* Removes and returns the last element of the list.
---------------------------------------------------------------------------*/
{
if (IsEmpty())
THROW(TLXEmpty(LOCUS));
TLX_ASSERT_PTR(mTail);
return Extract(mTail);
}
/*-------------------------------------------------------------------------*/
bool TLSLBase::IsEmpty() const
/* Checks if the list is currently empty, returning nonzero if it is.
---------------------------------------------------------------------------*/
{
TLX_ASSERT(mCount > 0 || (mHead == 0 && mTail == 0));
return mCount == 0;
}
/*-------------------------------------------------------------------------*/
TLSLBase &TLSLBase::operator =(const TLSLBase &)
/* Assignment operator, does not copy anything.
---------------------------------------------------------------------------*/
{
return *this;
}
/*-------------------------------------------------------------------------*/
void TLSLBase::Prepend(TLSLink *aLink)
/* Adds a new link at the start of the current list. The new link should
not be 0 and not be part of a list yet.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT_NULL(aLink->mNext);
if (mHead)
aLink->Append(mHead);
else
mTail = aLink;
mHead = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
void TLSLBase::Prepend(TLSLink *aLink, TLSLink *aPos)
/* Inserts a link before another one. The link to insert should not
be 0 and not be part of a list yet.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT_PTR(aPos);
TLX_ASSERT_NULL(aLink->mNext);
TLX_ASSERT(Contains(aPos));
if (aPos == mHead)
{
aLink->Append(mHead);
mHead = aLink;
}
else
{
// Find the element preceding 'aPos'
TLSLink *rover;
for (rover = mHead; rover && rover->Next() != aPos;
rover = rover->Next())
;
if (rover)
{
TLX_ASSERT(rover->Next() == aPos);
rover->Append(aLink);
aLink->Append(aPos);
}
}
mCount++;
}
/*-------------------------------------------------------------------------*/
void TLSLBase::RemoveAll()
/* Removes all elements from the list. If the list owns its items, they
are deleted; else they are simply forgotten.
---------------------------------------------------------------------------*/
{
if (mOwner) CleanUp();
mHead = mTail = 0;
mCount = 0;
}
/*-------------------------------------------------------------------------*/
TLSLink *TLSLBase::Replace(TLSLink *aPos, TLSLink *aLink)
/* Replaces one link by another, returning the original link.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aPos);
TLX_ASSERT_PTR(aLink);
TLX_ASSERT(Contains(aPos));
// Insert the new link (before or after the original one), then remove
// and return the original link.
Append(aLink, aPos);
return Extract(aPos);
}
/*-------------------------------------------------------------------------*/
TLSLink *TLSLBase::Split(TLSLink *aLink)
/* Splits the list in two at the indicated position. The indicated link
will become the head of the new list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT(Contains(aLink));
if (mHead == aLink)
mHead = 0;
else
{
// Find the element preceding 'aLink'
TLSLink *rover;
for (rover = mHead; rover && rover->Next() != aLink;
rover = rover->Next())
;
if (rover)
{
TLX_ASSERT(rover->Next() == aLink);
rover->Unlink();
}
}
// Recount remaining elements
mCount = 0;
mTail = mHead;
while (mTail)
{
++mCount;
mTail = mTail->mNext;
}
return aLink;
}