home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmring.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  4.4 KB  |  228 lines

  1. // CmRing.cpp
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Ring (circular linked list) implementation.
  7. // -----------------------------------------------------------------
  8.  
  9. #include <cm/include/cmring.h>
  10.  
  11.  
  12. // "CmRing" is the ring copy constructor.
  13. //
  14. CmRing::CmRing(const CmRing& R)
  15. {
  16.   _top  = NULL;
  17.   _last = NULL;
  18.   copy(R);
  19. }
  20.  
  21.  
  22. // "~CmRing" is the ring destructor.
  23. //
  24. CmRing::~CmRing()
  25. {
  26.   removeAll();
  27. }
  28.  
  29.  
  30. // "=" assignment operator copies the specified ring into this ring.
  31. //
  32. CmRing& CmRing::operator=(const CmRing& R)
  33. {
  34.   if (&R != this)
  35.   {
  36.     removeAll();
  37.     copy     (R);
  38.   }
  39.   return *this;
  40. }
  41.  
  42.  
  43. // "add" adds the specified object to the top of the ring.
  44. //
  45. Bool CmRing::add(CmObject* pObj)
  46. {
  47.   if (!pObj) return FALSE;
  48.   CmRingNode *newnode = new CmRingNode(pObj);
  49.   if (!newnode) return FALSE;
  50.  
  51.   if (!_top)
  52.   {
  53.     _top = _last = newnode;
  54.     newnode->_next = _top;
  55.   }
  56.   else
  57.   {
  58.     newnode->_next = _top;
  59.     _top           = newnode;
  60.     _last->_next   = newnode;
  61.   }
  62.   _size++;
  63.   return TRUE;
  64. }
  65.  
  66.  
  67. // "remove" removes the first occurrence of an object which isEqual to the
  68. // specified object.
  69. //
  70. Bool CmRing::remove(CmObject* pObj)
  71. {
  72.   if (!pObj || !_top) return FALSE;
  73.  
  74.   if (_top->_data->isEqual(pObj)) return removeTop();
  75.  
  76.   CmRingNode *rover1 = _top;
  77.   CmRingNode *rover2 = _top;
  78.  
  79.   while (rover1 != NULL && !(rover1->_data->isEqual(pObj)))
  80.   {
  81.     rover2 = rover1;
  82.     rover1 = rover1->_next;
  83.   }
  84.  
  85.   if (rover1 == NULL) return FALSE;
  86.  
  87.   if (rover1 == _last) _last = rover2;
  88.   rover2->_next = rover2->_next->_next;
  89.  
  90.   if (ownsObjects()) delete rover1->_data;
  91.   delete rover1;
  92.   _size--;
  93.   return TRUE;
  94. }
  95.  
  96.  
  97. // "removeTop" removes the top object from the ring.
  98. //
  99. Bool CmRing::removeTop()
  100. {
  101.   if (!_top) return FALSE;
  102.  
  103.   if (ownsObjects()) delete _top->_data;
  104.   if (_size == 1)
  105.   {
  106.     delete _top;
  107.     _top = _last = NULL;
  108.   }
  109.   else
  110.   {
  111.     CmRingNode *temp = _top;
  112.     _top = _top->_next;
  113.     _last->_next = _top;
  114.     delete temp;
  115.   }
  116.   _size--;
  117.   return TRUE;
  118. }
  119.  
  120.  
  121. // "lookup" returns a pointer to the first occurrence of an object
  122. // which isEqual to the specified object.
  123. //
  124. CmObject* CmRing::lookup(CmObject* pObj) const
  125. {
  126.   if (!pObj || !_top) return NULL;
  127.   CmRingNode *rover = _top;
  128.   int          ii    = 0;
  129.   CmObject   *ret   = NULL;
  130.   while (ii < _size && !ret)
  131.   {
  132.     if (rover->_data->isEqual(pObj))
  133.       ret = rover->_data;
  134.     else
  135.     {
  136.       rover = rover->_next;
  137.       ii++;
  138.     }
  139.   }
  140.   return ret;
  141. }
  142.  
  143.  
  144. // "contains" returns TRUE if the ring contains an object which isEqual
  145. // to the specified object.
  146. //
  147. Bool CmRing::contains(CmObject* pObj) const
  148. {
  149.   return (lookup(pObj) != NULL);
  150. }
  151.  
  152.  
  153. // "occurrences" counts the number of objects that isEqual to the specified
  154. // object.
  155. //
  156. unsigned CmRing::occurrences(CmObject* pObj) const
  157. {
  158.   if (!pObj || !_top) return 0;
  159.   CmRingNode *rover = _top;
  160.   int          ii    = 0;
  161.   unsigned     occur = 0;
  162.   while (ii < _size)
  163.   {
  164.     if (rover->_data->isEqual(pObj)) occur++;
  165.     rover = rover->_next; ii++;
  166.   }
  167.   return occur;
  168. }
  169.  
  170.  
  171. // "removeAll" removes all of the objects from the ring.
  172. //
  173. void CmRing::removeAll()
  174. {
  175.   CmRingNode *rover = _top;
  176.   int          ii    = 0;
  177.   while (ii < _size)
  178.   {
  179.     CmRingNode *temp = rover->_next;
  180.     if (ownsObjects()) delete rover->_data;
  181.     delete rover;
  182.     rover = temp;
  183.     ii++;
  184.   }
  185.   _top  = _last = NULL;
  186.   _size = 0;
  187. }
  188.  
  189.  
  190. // "newIterator" creates and returns a new ring iterator.
  191. //
  192. CmIterator* CmRing::newIterator() const
  193. {
  194.   return new CmRingIterator(*this);
  195. }
  196.  
  197.  
  198. // "next" returns the current ring object and advances the iterator
  199. // to the next object.
  200. //
  201. CmObject* CmRingIterator::next()
  202. {
  203.   if (!_node) return NULL;
  204.   CmObject *rval = _node->_data;
  205.   _node = _node->_next;
  206.   return rval;
  207. }
  208.  
  209.  
  210. // "previous" backs the iterator up one object and returns that object.
  211. //
  212. CmObject* CmRingIterator::previous()
  213. {
  214.   if (!_node) return NULL;
  215.   CmObject *rval = _node->_data;
  216.  
  217.   if (_node == _ring._top)
  218.     _node = _ring._last;
  219.   else
  220.   {
  221.     CmRingNode *rover = _ring._top;
  222.     while (rover && rover->_next != _node)
  223.       rover = rover->_next;
  224.     _node = rover;
  225.   }
  226.   return rval;
  227. }
  228.