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

  1. /****************************************************************************
  2.     $Id: slcbase.cpp 501.0 1995/03/07 12:26:22 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 TLSLCBase.
  10.  
  11.     $Log: slcbase.cpp $
  12.     Revision 501.0  1995/03/07 12:26:22  RON
  13.     Updated for TLX 5.01
  14.     Revision 1.7  1995/01/31 16:30:24  RON
  15.     Update for release 012
  16.     Added partial support for SunPro C++ compiler
  17.     Revision 1.6  1995/01/06  15:58:19  ron
  18.     Corrected Revision keyword
  19.  
  20.     Revision 1.5  1994/11/16  15:42:59  ron
  21.     Added module info; rearranged #include directives
  22.  
  23.     Revision 1.4  1994/09/28  14:21:39  ron
  24.     Removed Macintosh-style #include references
  25.  
  26.     Revision 1.3  1994/09/27  20:22:59  ron
  27.     Changed path separator from / to \
  28.  
  29.     Revision 1.2  1994/09/26  15:47:23  ron
  30.     Changed include file references
  31.  
  32.     Revision 1.1  1994/08/16  18:13:13  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\except.h>        // Exception handling
  42. #include <tlx\501\slists.h>        // Class declaration
  43.  
  44. /*-------------------------------------------------------------------------*/
  45.     TLSLCBase::TLSLCBase(bool aOwner)
  46.  
  47. /*  Constructor, also doubles as default constructor. Creates an empty list.
  48. ---------------------------------------------------------------------------*/
  49. : mTail(0), mCount(0), mOwner(aOwner)
  50. {
  51. }
  52.  
  53. /*-------------------------------------------------------------------------*/
  54.     TLSLCBase::TLSLCBase(const TLSLCBase &)
  55.  
  56. /*  Copy constructor. Does not copy the list.
  57. ---------------------------------------------------------------------------*/
  58. : mTail(0), mCount(0), mOwner(false)
  59. {
  60. }
  61.  
  62. /*-------------------------------------------------------------------------*/
  63.     TLSLCBase::~TLSLCBase()
  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 TLSLCBase::Append(TLSLink *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.  
  81.     if (mTail)
  82.     {
  83.     aLink->Append(mTail->Next());
  84.     mTail->Append(aLink);
  85.     }
  86.     else            // Create a single element list
  87.     {
  88.     TLX_ASSERT(mCount == 0);
  89.     aLink->Append(aLink);
  90.     }
  91.     mTail = aLink;
  92.  
  93.     mCount++;
  94. }
  95.  
  96. /*-------------------------------------------------------------------------*/
  97.     void TLSLCBase::Append(TLSLink *aLink, TLSLink *aPos)
  98.  
  99. /*  Inserts a link after another link in the list. The link to insert must
  100.     not be 0 and must not currently be part of a list.
  101. ---------------------------------------------------------------------------*/
  102. {
  103.     TLX_ASSERT_PTR(aLink);
  104.     TLX_ASSERT_PTR(aPos);
  105.     TLX_ASSERT_NULL(aLink->mNext);
  106.     TLX_ASSERT(Contains(aPos));
  107.  
  108.     aPos->Append(aLink);
  109.     aLink->Append(aPos->Next());
  110.  
  111.     if (aPos == mTail)
  112.     mTail = aLink;
  113.  
  114.     mCount++;
  115. }
  116.  
  117. /*-------------------------------------------------------------------------*/
  118.     bool TLSLCBase::BecomeOwner(bool aOwner)
  119.  
  120. /*  Changes the owner status, returning the previous status.
  121. ---------------------------------------------------------------------------*/
  122. {
  123.     bool oldstat = mOwner;
  124.     mOwner = aOwner;
  125.     return oldstat;
  126. }
  127.  
  128. /*-------------------------------------------------------------------------*/
  129.     void TLSLCBase::CleanUp()
  130.  
  131. /*  Deletes all elements in the list. The list should be owner for
  132.     this function to be called.
  133. ---------------------------------------------------------------------------*/
  134. {
  135.     TLX_ASSERT(mOwner);
  136.     if (!mTail) return;
  137.  
  138.     TLSLink *rover = mTail;
  139.     do
  140.     {
  141.     TLX_ASSERT_PTR(rover);
  142.  
  143.     TLSLink *tmp = rover;
  144.     rover = rover->Next();
  145.     tmp->Unlink();
  146.     delete tmp;
  147.     }
  148.     while (rover != mTail);
  149. }
  150.  
  151. /*-------------------------------------------------------------------------*/
  152.     bool TLSLCBase::Contains(TLSLink *aLink) const
  153.  
  154. /*  Tests whether a given element appears in the list, returning nonzero
  155.     if it does.
  156. ---------------------------------------------------------------------------*/
  157. {
  158.     if (!aLink) return false;
  159.  
  160.     for (TLSLink *rover = mTail->Next(); rover; rover = rover->Next())
  161.     {
  162.     if (rover == aLink)
  163.         return true;
  164.     if (rover == mTail)
  165.         break;
  166.     }
  167.     return false;
  168. }
  169.  
  170. /*-------------------------------------------------------------------------*/
  171.     void TLSLCBase::RemoveAll()
  172.  
  173. /*  Removes all elements from the list. If the list owns its items, they
  174.     are deleted; else they are simply forgotten.
  175. ---------------------------------------------------------------------------*/
  176. {
  177.     if (mOwner) CleanUp();
  178.     mTail  = 0;
  179.     mCount = 0;
  180. }
  181.  
  182. /*-------------------------------------------------------------------------*/
  183.     TLSLink *TLSLCBase::Extract(TLSLink *aLink)
  184.  
  185. /*  Removes and returns a specific link from the list.
  186. ---------------------------------------------------------------------------*/
  187. {
  188.     TLX_ASSERT_PTR(mTail);
  189.     TLX_ASSERT_PTR(aLink);
  190.     TLX_ASSERT(Contains(aLink));
  191.  
  192.     // Find the element preceding aLink
  193.  
  194.     for (TLSLink *rover = mTail->Next(); rover; rover = rover->Next())
  195.     {
  196.     if (rover->Next() == aLink)
  197.     {
  198.         // rover points to the element preceding aLink, which could be
  199.         // aLink itself. In the latter case, the list will become empty.
  200.  
  201.         if (rover == aLink)
  202.         {
  203.         // List becomes empty
  204.         mTail = 0;
  205.         }
  206.         else
  207.         {
  208.         rover->Append(aLink->Next());
  209.         if (aLink == mTail)
  210.             mTail = rover;
  211.         }
  212.         break;
  213.     }
  214.     else if (rover == mTail)
  215.         THROW(TLXNotFound(LOCUS));
  216.     }
  217.  
  218.     aLink->Unlink();
  219.     TLX_ASSERT(mCount > 0);
  220.     mCount--;
  221.  
  222.     return aLink;
  223. }
  224.  
  225. /*-------------------------------------------------------------------------*/
  226.     TLSLink *TLSLCBase::ExtractHead()
  227.  
  228. /*  Removes and returns the first element of the list.
  229. ---------------------------------------------------------------------------*/
  230. {
  231.     if (IsEmpty())
  232.     THROW(TLXEmpty(LOCUS));
  233.  
  234.     return Extract(mTail->Next());
  235. }
  236.  
  237. /*-------------------------------------------------------------------------*/
  238.     TLSLink *TLSLCBase::ExtractTail()
  239.  
  240. /*  Removes and returns the last element of the list.
  241. ---------------------------------------------------------------------------*/
  242. {
  243.     if (IsEmpty())
  244.     THROW(TLXEmpty(LOCUS));
  245.  
  246.     return Extract(mTail);
  247. }
  248.  
  249. /*-------------------------------------------------------------------------*/
  250.     bool TLSLCBase::IsEmpty() const
  251.  
  252. /*  Checks if the list is currently empty, returning nonzero if it is.
  253. ---------------------------------------------------------------------------*/
  254. {
  255.     TLX_ASSERT(mCount > 0 || mTail == 0);
  256.     return mCount == 0;
  257. }
  258.  
  259. /*-------------------------------------------------------------------------*/
  260.     TLSLCBase &TLSLCBase::operator =(const TLSLCBase &)
  261.  
  262. /*  Assignment operator, does not copy anything.
  263. ---------------------------------------------------------------------------*/
  264. {
  265.     return *this;
  266. }
  267.  
  268. /*-------------------------------------------------------------------------*/
  269.     void TLSLCBase::Prepend(TLSLink *aLink)
  270.  
  271. /*  Adds a new link at the start of the current list. The new link
  272.     must not be 0 and must not be part of a list yet.
  273. ---------------------------------------------------------------------------*/
  274. {
  275.     TLX_ASSERT_PTR(aLink);
  276.     TLX_ASSERT_NULL(aLink->mNext);
  277.  
  278.     if (mTail)
  279.     {
  280.     aLink->Append(mTail->Next());
  281.     mTail->Append(aLink);
  282.     }
  283.     else            // Make a single element list
  284.     {
  285.     aLink->Append(aLink);
  286.     mTail = aLink;
  287.     }
  288.  
  289.     mCount++;
  290. }
  291.  
  292. /*-------------------------------------------------------------------------*/
  293.     void TLSLCBase::Prepend(TLSLink *aLink, TLSLink *aPos)
  294.  
  295. /*  Inserts a link before another one. The link to insert must not be 0
  296.     and must not be part of a list yet.
  297. ---------------------------------------------------------------------------*/
  298. {
  299.     TLX_ASSERT_PTR(aLink);
  300.     TLX_ASSERT_PTR(aPos);
  301.     TLX_ASSERT_NULL(aLink->mNext);
  302.     TLX_ASSERT(Contains(aPos));
  303.  
  304.     // Find the element preceding aPos
  305.  
  306.     for (TLSLink *rover = mTail->Next(); rover; rover = rover->Next())
  307.     {
  308.     if (rover->Next() == aPos)
  309.     {
  310.         // rover points to the element preceding aPos, which could be
  311.         // aPos itself.
  312.  
  313.         aLink->Append(aPos);
  314.         rover->Append(aLink);
  315.         break;
  316.     }
  317.     else if (rover == mTail)
  318.         THROW(TLXNotFound(LOCUS));
  319.     }
  320.  
  321.     mCount++;
  322. }
  323.  
  324.