home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tlx501.zip / SRC / DLCBASE.CPP < prev    next >
C/C++ Source or Header  |  1996-07-08  |  8KB  |  284 lines

  1. /****************************************************************************
  2.     $Id: dlcbase.cpp 501.0 1995/03/07 12:26:12 RON Exp $
  3.  
  4.     Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
  5.  
  6.     Project:    Tarma Library for C++ V5.0
  7.     Author:    Ron van der Wal
  8.  
  9.     Implementation of class TLDLCBase.
  10.  
  11.     $Log: dlcbase.cpp $
  12.     Revision 501.0  1995/03/07 12:26:12  RON
  13.     Updated for TLX 5.01
  14.     Revision 1.7  1995/01/31 16:30:10  RON
  15.     Update for release 012
  16.     Added partial support for SunPro C++ compiler
  17.     Revision 1.6  1995/01/06  15:57:37  ron
  18.     Corrected Revision keyword
  19.  
  20.     Revision 1.5  1994/11/16  15:38:31  ron
  21.     Added module info; rearranged #include directives
  22.  
  23.     Revision 1.4  1994/09/28  14:17:03  ron
  24.     Removed Macintosh-style #include references
  25.  
  26.     Revision 1.3  1994/09/27  20:22:14  ron
  27.     Changed path separator from / to \
  28.  
  29.     Revision 1.2  1994/09/26  15:41:42  ron
  30.     Changed include file references
  31.  
  32.     Revision 1.1  1994/08/16  18:12:59  ron
  33.     Initial revision
  34.  
  35. ****************************************************************************/
  36.  
  37. #include <tlx\501\_build.h>
  38.  
  39. TLX_MODULE_INFO("$Revision: 501.0 $");
  40.  
  41. #include <tlx\501\dlists.h>        // Class declaration
  42. #include <tlx\501\except.h>        // Exception handling
  43.  
  44. /*-------------------------------------------------------------------------*/
  45.     TLDLCBase::TLDLCBase(bool aOwner)
  46.  
  47. /*  Constructor, also doubles as default constructor. Creates an empty list.
  48. ---------------------------------------------------------------------------*/
  49. : mHead(0), mCount(0), mOwner(aOwner)
  50. {
  51. }
  52.  
  53. /*-------------------------------------------------------------------------*/
  54.     TLDLCBase::TLDLCBase(const TLDLCBase &)
  55.  
  56. /*  Copy constructor. Does not copy the list.
  57. ---------------------------------------------------------------------------*/
  58. : mHead(0), mCount(0), mOwner(false)
  59. {
  60. }
  61.  
  62. /*-------------------------------------------------------------------------*/
  63.     TLDLCBase::~TLDLCBase()
  64.  
  65. /*  Destructor. If the list is owner of its elements, they are deleted.
  66. ---------------------------------------------------------------------------*/
  67. {
  68.     if (mOwner) CleanUp();
  69. }
  70.  
  71. /*-------------------------------------------------------------------------*/
  72.     void TLDLCBase::Append(TLDLink *aLink)
  73.  
  74. /*  Adds an element at the end of the list. The element pointer must be
  75.     nonzero, and the element must not currently be part of a list.
  76. ---------------------------------------------------------------------------*/
  77. {
  78.     TLX_ASSERT_PTR(aLink);
  79.     TLX_ASSERT_NULL(aLink->mNext);
  80.     TLX_ASSERT_NULL(aLink->mPrev);
  81.  
  82.     if (mHead)
  83.     mHead->Prepend(aLink);
  84.     else            // Create a single element list
  85.     {
  86.     TLX_ASSERT(mCount == 0);
  87.     aLink->mNext = aLink;
  88.     aLink->mPrev = aLink;
  89.     mHead = aLink;
  90.     }
  91.  
  92.     mCount++;
  93. }
  94.  
  95. /*-------------------------------------------------------------------------*/
  96.     void TLDLCBase::Append(TLDLink *aLink, TLDLink *aPos)
  97.  
  98. /*  Inserts a link after another link in the list. The link to insert must
  99.     not be 0 and must not currently be part of a list.
  100. ---------------------------------------------------------------------------*/
  101. {
  102.     TLX_ASSERT_PTR(aLink);
  103.     TLX_ASSERT_PTR(aPos);
  104.     TLX_ASSERT_NULL(aLink->mNext);
  105.     TLX_ASSERT_NULL(aLink->mPrev);
  106.     TLX_ASSERT(Contains(aPos));
  107.  
  108.     aPos->Append(aLink);
  109.     mCount++;
  110. }
  111.  
  112. /*-------------------------------------------------------------------------*/
  113.     bool TLDLCBase::BecomeOwner(bool aOwner)
  114.  
  115. /*  Changes the owner status, returning the previous status.
  116. ---------------------------------------------------------------------------*/
  117. {
  118.     bool oldstat = mOwner;
  119.     mOwner = aOwner;
  120.     return oldstat;
  121. }
  122.  
  123. /*-------------------------------------------------------------------------*/
  124.     void TLDLCBase::CleanUp()
  125.  
  126. /*  Deletes all elements in the list. The list should be owner for
  127.     this function to be called.
  128. ---------------------------------------------------------------------------*/
  129. {
  130.     TLX_ASSERT(mOwner);
  131.     if (!mHead) return;
  132.  
  133.     TLDLink *rover = mHead;
  134.     do
  135.     {
  136.     TLX_ASSERT_PTR(rover);
  137.  
  138.     TLDLink *tmp = rover;
  139.     rover = rover->Next();
  140.     tmp->Unlink();
  141.     delete tmp;
  142.     }
  143.     while (rover != mHead);
  144. }
  145.  
  146. /*-------------------------------------------------------------------------*/
  147.     bool TLDLCBase::Contains(TLDLink *aLink) const
  148.  
  149. /*  Tests whether a given element appears in the list, returning nonzero
  150.     if it does.
  151. ---------------------------------------------------------------------------*/
  152. {
  153.     if (!aLink) return false;
  154.  
  155.     for (TLDLink *rover = mHead; rover; rover = rover->Next())
  156.     {
  157.     if (rover == aLink)
  158.         return true;
  159.     if (rover->Next() == mHead)
  160.         break;
  161.     }
  162.  
  163.     return false;
  164. }
  165.  
  166. /*-------------------------------------------------------------------------*/
  167.     void TLDLCBase::RemoveAll()
  168.  
  169. /*  Removes all elements from the list. If the list owns its items, they
  170.     are deleted; else they are simply forgotten.
  171. ---------------------------------------------------------------------------*/
  172. {
  173.     if (mOwner) CleanUp();
  174.     mHead  = 0;
  175.     mCount = 0;
  176. }
  177.  
  178. /*-------------------------------------------------------------------------*/
  179.     TLDLink *TLDLCBase::Extract(TLDLink *aLink)
  180.  
  181. /*  Removes and returns a specific link from the list.
  182. ---------------------------------------------------------------------------*/
  183. {
  184.     TLX_ASSERT_PTR(mHead);
  185.     TLX_ASSERT_PTR(aLink);
  186.     TLX_ASSERT(Contains(aLink));
  187.  
  188.     if (aLink == mHead) mHead = aLink->Next();
  189.     if (aLink == mHead) mHead = 0;    // List consisted of a single element
  190.  
  191.     aLink->Unlink();
  192.     TLX_ASSERT(mCount > 0);
  193.     mCount--;
  194.  
  195.     return aLink;
  196. }
  197.  
  198. /*-------------------------------------------------------------------------*/
  199.     TLDLink *TLDLCBase::ExtractHead()
  200.  
  201. /*  Removes and returns the first element of the list.
  202. ---------------------------------------------------------------------------*/
  203. {
  204.     if (IsEmpty())
  205.     THROW(TLXEmpty(LOCUS));
  206.  
  207.     return Extract(mHead);
  208. }
  209.  
  210. /*-------------------------------------------------------------------------*/
  211.     TLDLink *TLDLCBase::ExtractTail()
  212.  
  213. /*  Removes and returns the last element of the list.
  214. ---------------------------------------------------------------------------*/
  215. {
  216.     if (IsEmpty())
  217.     THROW(TLXEmpty(LOCUS));
  218.  
  219.     TLX_ASSERT_PTR(mHead);
  220.     TLX_ASSERT_PTR(mHead->mPrev);
  221.     return Extract(mHead->mPrev);
  222. }
  223.  
  224. /*-------------------------------------------------------------------------*/
  225.     bool TLDLCBase::IsEmpty() const
  226.  
  227. /*  Checks if the list is currently empty, returning nonzero if it is.
  228. ---------------------------------------------------------------------------*/
  229. {
  230.     TLX_ASSERT(mCount > 0 || mHead == 0);
  231.     return mCount == 0;
  232. }
  233.  
  234. /*-------------------------------------------------------------------------*/
  235.     TLDLCBase &TLDLCBase::operator =(const TLDLCBase &)
  236.  
  237. /*  Assignment operator, does not copy anything.
  238. ---------------------------------------------------------------------------*/
  239. {
  240.     return *this;
  241. }
  242.  
  243. /*-------------------------------------------------------------------------*/
  244.     void TLDLCBase::Prepend(TLDLink *aLink)
  245.  
  246. /*  Adds a new link at the start of the current list. The new link
  247.     must not be 0 and must not be part of a list yet.
  248. ---------------------------------------------------------------------------*/
  249. {
  250.     TLX_ASSERT_PTR(aLink);
  251.     TLX_ASSERT_NULL(aLink->mNext);
  252.     TLX_ASSERT_NULL(aLink->mPrev);
  253.  
  254.     if (mHead)
  255.     mHead->Prepend(aLink);
  256.     else            // Make a single element list
  257.     {
  258.     aLink->mNext = aLink;
  259.     aLink->mPrev = aLink;
  260.     }
  261.  
  262.     mHead = aLink;
  263.     mCount++;
  264. }
  265.  
  266. /*-------------------------------------------------------------------------*/
  267.     void TLDLCBase::Prepend(TLDLink *aLink, TLDLink *aPos)
  268.  
  269. /*  Inserts a link before another one. The link to insert must not be 0
  270.     and must not be part of a list yet.
  271. ---------------------------------------------------------------------------*/
  272. {
  273.     TLX_ASSERT_PTR(aLink);
  274.     TLX_ASSERT_PTR(aPos);
  275.     TLX_ASSERT_NULL(aLink->mNext);
  276.     TLX_ASSERT_NULL(aLink->mPrev);
  277.     TLX_ASSERT(Contains(aPos));
  278.  
  279.     aPos->Prepend(aLink);
  280.     if (aPos == mHead) mHead = aLink;
  281.     mCount++;
  282. }
  283.  
  284.