home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
DLBASE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
11KB
|
363 lines
/****************************************************************************
$Id: dlbase.cpp 501.0 1995/03/07 12:26:12 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 TLDLBase.
$Log: dlbase.cpp $
Revision 501.0 1995/03/07 12:26:12 RON
Updated for TLX 5.01
Revision 1.7 1995/01/31 16:30:10 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.6 1995/01/06 15:57:36 ron
Corrected Revision keyword
Revision 1.5 1994/11/16 15:38:25 ron
Added module info; rearranged #include directives
Revision 1.4 1994/09/28 14:16:55 ron
Removed Macintosh-style #include references
Revision 1.3 1994/09/27 20:22:12 ron
Changed path separator from / to \
Revision 1.2 1994/09/26 15:41:33 ron
Changed include file references
Revision 1.1 1994/08/16 18:12:58 ron
Initial revision
****************************************************************************/
#include <tlx\501\_build.h>
TLX_MODULE_INFO("$Revision: 501.0 $");
#include <tlx\501\dlists.h> // Class declaration
#include <tlx\501\except.h> // Exception handling
/*-------------------------------------------------------------------------*/
TLDLBase::TLDLBase(bool aOwner)
/* Constructor, also doubles as default constructor. Creates an empty list.
---------------------------------------------------------------------------*/
: mHead(0), mTail(0), mCount(0), mOwner(aOwner)
{
}
/*-------------------------------------------------------------------------*/
TLDLBase::TLDLBase(const TLDLBase &)
/* Copy constructor, does not copy the other list.
---------------------------------------------------------------------------*/
: mHead(0), mTail(0), mCount(0), mOwner(false)
{
}
/*-------------------------------------------------------------------------*/
TLDLBase::~TLDLBase()
/* Destructor. If the list is woner of its elements at the time of
destruction, it deletes all its elements.
---------------------------------------------------------------------------*/
{
if (mOwner) CleanUp();
}
/*-------------------------------------------------------------------------*/
void TLDLBase::Append(TLDLink *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);
TLX_ASSERT_NULL(aLink->mPrev);
if (mTail)
mTail->Append(aLink);
else
mHead = aLink;
mTail = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
void TLDLBase::Append(TLDLink *aLink, TLDLink *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_NULL(aLink->mPrev);
TLX_ASSERT(Contains(aPos));
aPos->Append(aLink);
if (aPos == mTail)
mTail = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
bool TLDLBase::BecomeOwner(bool aOwner)
/* Changes the owner status, returning the previous status.
---------------------------------------------------------------------------*/
{
bool oldstat = mOwner;
mOwner = aOwner;
return oldstat;
}
/*-------------------------------------------------------------------------*/
void TLDLBase::CleanUp()
/* Deletes all elements in the list. The list should be owner for this
function to be called.
---------------------------------------------------------------------------*/
{
TLX_ASSERT(mOwner);
TLDLink *rover = mHead;
while (rover)
{
TLDLink *tmp = rover;
rover = rover->Next();
tmp->Unlink();
delete tmp;
}
}
/*-------------------------------------------------------------------------*/
void TLDLBase::Concat(TLDLink *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);
TLX_ASSERT_NULL(aList->mPrev);
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 TLDLBase::Concat(TLDLBase &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 TLDLBase::Contains(TLDLink *aLink) const
/* Tests whether a given element appears in the list. The function performs
a linear search.
---------------------------------------------------------------------------*/
{
if (!aLink) return false;
for (TLDLink *rover = mHead; rover; rover = rover->Next())
if (rover == aLink)
return true;
return false;
}
/*-------------------------------------------------------------------------*/
TLDLink *TLDLBase::Extract(TLDLink *aLink)
/* Removes and returns a specific link from the list.
---------------------------------------------------------------------------*/
{
TLX_ASSERT_PTR(aLink);
TLX_ASSERT(Contains(aLink));
if (aLink == mHead) mHead = aLink->Next();
if (aLink == mTail) mTail = aLink->Prev();
aLink->Unlink();
TLX_ASSERT(mCount > 0);
mCount--;
return aLink;
}
/*-------------------------------------------------------------------------*/
TLDLink *TLDLBase::ExtractHead()
/* Removes and returns the first element of the list.
---------------------------------------------------------------------------*/
{
if (IsEmpty())
THROW(TLXEmpty(LOCUS));
TLX_ASSERT_PTR(mHead);
return Extract(mHead);
}
/*-------------------------------------------------------------------------*/
TLDLink *TLDLBase::ExtractTail()
/* Removes and returns the last element of the list.
---------------------------------------------------------------------------*/
{
if (IsEmpty())
THROW(TLXEmpty(LOCUS));
TLX_ASSERT_PTR(mTail);
return Extract(mTail);
}
/*-------------------------------------------------------------------------*/
bool TLDLBase::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;
}
/*-------------------------------------------------------------------------*/
TLDLBase &TLDLBase::operator =(const TLDLBase &)
/* Assignment operator, does not copy anything.
---------------------------------------------------------------------------*/
{
return *this;
}
/*-------------------------------------------------------------------------*/
void TLDLBase::Prepend(TLDLink *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);
TLX_ASSERT_NULL(aLink->mPrev);
if (mHead)
mHead->Prepend(aLink);
else
mTail = aLink;
mHead = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
void TLDLBase::Prepend(TLDLink *aLink, TLDLink *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_NULL(aLink->mPrev);
TLX_ASSERT(Contains(aPos));
aPos->Prepend(aLink);
if (aPos == mHead)
mHead = aLink;
mCount++;
}
/*-------------------------------------------------------------------------*/
void TLDLBase::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;
}
/*-------------------------------------------------------------------------*/
TLDLink *TLDLBase::Replace(TLDLink *aPos, TLDLink *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);
}
/*-------------------------------------------------------------------------*/
TLDLink *TLDLBase::Split(TLDLink *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)
{
TLX_ASSERT_NULL(aLink->mPrev);
mHead = 0;
}
mTail = aLink->mPrev;
aLink->mPrev->mNext = 0;
aLink->mPrev = 0;
// Recount remaining elements
mCount = 0;
mTail = mHead;
while (mTail)
{
++mCount;
mTail = mTail->mNext;
}
return aLink;
}