home *** CD-ROM | disk | FTP | other *** search
- // CmRing.cpp
- // -----------------------------------------------------------------
- // Compendium - C++ Container Class Library
- // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
- // -----------------------------------------------------------------
- // Ring (circular linked list) implementation.
- // -----------------------------------------------------------------
-
- #include <cm/include/cmring.h>
-
-
- // "CmRing" is the ring copy constructor.
- //
- CmRing::CmRing(const CmRing& R)
- {
- _top = NULL;
- _last = NULL;
- copy(R);
- }
-
-
- // "~CmRing" is the ring destructor.
- //
- CmRing::~CmRing()
- {
- removeAll();
- }
-
-
- // "=" assignment operator copies the specified ring into this ring.
- //
- CmRing& CmRing::operator=(const CmRing& R)
- {
- if (&R != this)
- {
- removeAll();
- copy (R);
- }
- return *this;
- }
-
-
- // "add" adds the specified object to the top of the ring.
- //
- Bool CmRing::add(CmObject* pObj)
- {
- if (!pObj) return FALSE;
- CmRingNode *newnode = new CmRingNode(pObj);
- if (!newnode) return FALSE;
-
- if (!_top)
- {
- _top = _last = newnode;
- newnode->_next = _top;
- }
- else
- {
- newnode->_next = _top;
- _top = newnode;
- _last->_next = newnode;
- }
- _size++;
- return TRUE;
- }
-
-
- // "remove" removes the first occurrence of an object which isEqual to the
- // specified object.
- //
- Bool CmRing::remove(CmObject* pObj)
- {
- if (!pObj || !_top) return FALSE;
-
- if (_top->_data->isEqual(pObj)) return removeTop();
-
- CmRingNode *rover1 = _top;
- CmRingNode *rover2 = _top;
-
- while (rover1 != NULL && !(rover1->_data->isEqual(pObj)))
- {
- rover2 = rover1;
- rover1 = rover1->_next;
- }
-
- if (rover1 == NULL) return FALSE;
-
- if (rover1 == _last) _last = rover2;
- rover2->_next = rover2->_next->_next;
-
- if (ownsObjects()) delete rover1->_data;
- delete rover1;
- _size--;
- return TRUE;
- }
-
-
- // "removeTop" removes the top object from the ring.
- //
- Bool CmRing::removeTop()
- {
- if (!_top) return FALSE;
-
- if (ownsObjects()) delete _top->_data;
- if (_size == 1)
- {
- delete _top;
- _top = _last = NULL;
- }
- else
- {
- CmRingNode *temp = _top;
- _top = _top->_next;
- _last->_next = _top;
- delete temp;
- }
- _size--;
- return TRUE;
- }
-
-
- // "lookup" returns a pointer to the first occurrence of an object
- // which isEqual to the specified object.
- //
- CmObject* CmRing::lookup(CmObject* pObj) const
- {
- if (!pObj || !_top) return NULL;
- CmRingNode *rover = _top;
- int ii = 0;
- CmObject *ret = NULL;
- while (ii < _size && !ret)
- {
- if (rover->_data->isEqual(pObj))
- ret = rover->_data;
- else
- {
- rover = rover->_next;
- ii++;
- }
- }
- return ret;
- }
-
-
- // "contains" returns TRUE if the ring contains an object which isEqual
- // to the specified object.
- //
- Bool CmRing::contains(CmObject* pObj) const
- {
- return (lookup(pObj) != NULL);
- }
-
-
- // "occurrences" counts the number of objects that isEqual to the specified
- // object.
- //
- unsigned CmRing::occurrences(CmObject* pObj) const
- {
- if (!pObj || !_top) return 0;
- CmRingNode *rover = _top;
- int ii = 0;
- unsigned occur = 0;
- while (ii < _size)
- {
- if (rover->_data->isEqual(pObj)) occur++;
- rover = rover->_next; ii++;
- }
- return occur;
- }
-
-
- // "removeAll" removes all of the objects from the ring.
- //
- void CmRing::removeAll()
- {
- CmRingNode *rover = _top;
- int ii = 0;
- while (ii < _size)
- {
- CmRingNode *temp = rover->_next;
- if (ownsObjects()) delete rover->_data;
- delete rover;
- rover = temp;
- ii++;
- }
- _top = _last = NULL;
- _size = 0;
- }
-
-
- // "newIterator" creates and returns a new ring iterator.
- //
- CmIterator* CmRing::newIterator() const
- {
- return new CmRingIterator(*this);
- }
-
-
- // "next" returns the current ring object and advances the iterator
- // to the next object.
- //
- CmObject* CmRingIterator::next()
- {
- if (!_node) return NULL;
- CmObject *rval = _node->_data;
- _node = _node->_next;
- return rval;
- }
-
-
- // "previous" backs the iterator up one object and returns that object.
- //
- CmObject* CmRingIterator::previous()
- {
- if (!_node) return NULL;
- CmObject *rval = _node->_data;
-
- if (_node == _ring._top)
- _node = _ring._last;
- else
- {
- CmRingNode *rover = _ring._top;
- while (rover && rover->_next != _node)
- rover = rover->_next;
- _node = rover;
- }
- return rval;
- }
-