home *** CD-ROM | disk | FTP | other *** search
- #ifndef __RWTVDLIST_H__
- #define __RWTVDLIST_H__
- pragma push_align_members(64);
-
- /*
- * RWTValDlist<T>: A non-intrusive doubly-linked list of values of type T.
- *
- * $Header: E:/vcs/rw/tvdlist.h_v 1.5 19 Mar 1992 11:26:02 KEFFER $
- *
- ****************************************************************************
- *
- * Rogue Wave Software, Inc.
- * P.O. Box 2328
- * Corvallis, OR 97339
- *
- * Copyright (C) 1992. This software is subject to copyright
- * protection under the laws of the United States and other countries.
- *
- ***************************************************************************
- *
- * Stores a *copy* of the inserted item into the collection.
- *
- * Assumes that T has:
- * - well-defined copy constructor (T::T(const T&) or equiv.);
- * - well-defined assignment operator (T::operator=(const T&) or equiv.);
- * - well-defined equality semantics (T::operator==(const T&)).
- *
- * Note that while these are automatically defined for builtin types
- * (such as "int", "double", or any pointer), you may need to provide
- * appropriate operators for your own classes, particularly those with
- * constructors and/or pointers to other objects.
- *
- ***************************************************************************
- *
- * $Log: E:/vcs/rw/tvdlist.h_v $
- *
- * Rev 1.5 19 Mar 1992 11:26:02 KEFFER
- *
- * Rev 1.0 02 Mar 1992 16:10:52 KEFFER
- * Initial revision.
- *
- */
-
- //$DECLARE_TEMPLATE
-
- #include "rw/tidlist.h"
-
- template <class T> class RWExport RWTValDlistIterator;
-
-
- /****************************************************************
- * *
- * Declarations for RWTValDlink<T> *
- * *
- ****************************************************************/
-
- /*
- * This is the actual link that is stored in the linked list.
- * It includes data of type "T".
- */
- template <class T> struct RWExport RWTValDlink : public RWIsvDlink {
- T _info;
- RWTValDlink(T a) : _info(a) { }
- };
-
-
- /****************************************************************
- * *
- * Declarations for RWTValDlist<T> *
- * *
- ****************************************************************/
-
- template <class T> class RWExport RWTValDlist : private RWTIsvDlist< RWTValDlink<T> > {
-
- friend class RWExport RWTValDlistIterator<T> ;
-
- // For convenience in what follows:
- typedef RWTValDlink<T> LINK;
- typedef RWTIsvDlist<LINK> BASE;
-
- protected: // Member functions
-
- T peel(LINK* link); // Extract "_info" out of link; throw away link
-
- // To repackage tester functions for the base class:
- static RWBoolean eqTestFun(const LINK* link, void* p);
- static RWBoolean valTestFun(const LINK* link, void* p);
-
- public:
-
- RWTValDlist() { }
- RWTValDlist(const RWTValDlist<T>&);
- ~RWTValDlist() { clear(); }
-
- // Operators:
- RWTValDlist& operator=(const RWTValDlist<T>&);
- T& operator[](int i) {return (T&)BASE::at(i)->_info;}
- T operator[](int i) const {return BASE::at(i)->_info;}
-
- /********************* Member functions **************************/
- void append(T a) {BASE::append(new LINK(a));}
- void apply(void (*applyFun)(T, void*), void*);
- T& at(int i) {return (T&)BASE::at(i)->_info;}
- T at(int i) const {return BASE::at(i)->_info;}
- void clear() {BASE::clearAndDestroy();}
- RWBoolean contains(RWBoolean (*testFun)(T, void*), void*) const;
- RWBoolean contains(T a) const;
- BASE::entries;
- RWBoolean find(T a, T& k) const; // Find first occurrence
- RWBoolean find(RWBoolean (*testFun)(T, void*), void*, T& k) const;
- T first() const {return BASE::first()->_info;}
- T get() {return peel(BASE::get());}
- int index(T a) const;
- int index(RWBoolean (*testFun)(T, void*), void*) const;
- void insert(T a) {BASE::append(new LINK(a));}
- void insertAfter(int i, T a) {BASE::insertAfter(i, new LINK(a));}
- void insertAt(int i, T a) {BASE::insertAt(i, new LINK(a));}
- BASE::isEmpty;
- T last() const {return BASE::last()->_info;}
- unsigned occurrencesOf(T a) const;
- unsigned occurrencesOf(RWBoolean (*testFun)(T, void*), void*) const;
- void prepend(T a) {BASE::prepend(new LINK(a));}
- RWBoolean remove(T a); // Remove first occurrence
- RWBoolean remove(RWBoolean (*testFun)(T, void*), void*); // Remove first occurrence
- unsigned removeAll(T a);
- unsigned removeAll(RWBoolean (*testFun)(T, void*), void*);
- T removeAt(int i) {return peel(BASE::removeAt(i));}
- T removeFirst() {return peel(BASE::removeFirst());}
- T removeLast() {return peel(BASE::removeLast());}
- };
-
- /****************************************************************
- * *
- * Declarations for RWTValDlistIterator<T> *
- * *
- ****************************************************************/
-
- template <class T> class RWExport RWTValDlistIterator : private RWTIsvDlistIterator< RWTValDlink<T> > {
-
- // For convenience in what follows:
- typedef RWTValDlist<T> LIST;
- typedef RWTValDlink<T> LINK;
- typedef RWTIsvDlistIterator<LINK> BASE;
-
- // Disallow postfix increment. Unless we hide it, some compilers will
- // substitute the prefix increment operator in its place.
- RWBoolean operator++(int);
-
- public:
-
- // Constructor: starts with iterator positioned at last link.
- RWTValDlistIterator(RWTValDlist<T>& s) : RWTIsvDlistIterator<LINK>(s) { }
-
- // Operators:
- RWBoolean operator++() {return BASE::operator++();}
- BASE::operator+=; // Advance iterator n links and test
- BASE::operator--;
-
- LIST* container() const {return (LIST*)BASE::container();}
- RWBoolean findNext(T a);
- RWBoolean findNext(RWBoolean (*testFun)(T, void*), void*);
- void insertAfterPoint(T a) {BASE::insertAfterPoint(new LINK(a));}
- T key() const {return BASE::key()->_info;}
- RWBoolean remove(); // Remove item at cursor
- RWBoolean removeNext(T);
- RWBoolean removeNext(RWBoolean (*testFun)(T, void*), void*);
- void reset() {BASE::reset();}
- void reset(LIST& s) {BASE::reset(s);}
- };
-
-
- //$IMPLEMENT_TEMPLATE
-
- #include "rw/tvtestr.h"
-
- /****************************************************************
- * *
- * Definitions for RWTValDlist<T> *
- * *
- ****************************************************************/
-
- // Used to test for equality with an object.
- template <class T> RWBoolean
- RWTValDlist<T>::eqTestFun(const RWTValDlink<T>* link, void* p)
- {
- RWPRECONDITION(link);
- RWPRECONDITION(p);
- const T* t = (const T*)p;
- return link->_info == *t;
- }
-
- // Function to wrap a user-supplied tester function such that it
- // can be used by the base class
- template <class T> RWBoolean
- RWTValDlist<T>::valTestFun(const RWTValDlink<T>* link, void* p)
- {
- RWPRECONDITION(link);
- RWPRECONDITION(p);
- RWTValTester<T>* c = (RWTValTester<T>*)p;
- return (*c->_testFun)(link->_info, c->_data);
- }
-
- // Copy constructor:
- template <class T> RWTValDlist<T>::RWTValDlist(const RWTValDlist<T>& s)
- {
- // Construct an iterator, casting away "constness"
- // (which we promise to honor anyway):
- RWTValDlistIterator<T> next((RWTValDlist<T>&)s);
- while (++next) append(next.key());
- }
-
- template <class T> RWTValDlist<T>&
- RWTValDlist<T>::operator=(const RWTValDlist<T>& s)
- {
- if (this!=&s){
- clear();
- // Construct an iterator, casting away "constness"
- // (which we promise to honor anyway):
- RWTValDlistIterator<T> next((RWTValDlist<T>&)s);
- while (++next) append(next.key());
- }
- return *this;
- }
-
- template <class T> void
- RWTValDlist<T>::apply(void (*applyFun)(T, void*), void* a)
- {
- RWIsvDlink* link = _lastDlink;
- if (link) {
- do {
- link = link->next(); // Advance to next link
- (*applyFun)(((RWTValDlink<T>*)link)->_info, a); // Apply the function
- } while (link != _lastDlink);
- }
- }
-
- template <class T> RWBoolean
- RWTValDlist<T>::contains(RWBoolean (*testFun)(T, void*), void* a) const
- {
- // Construct an iterator, casting away "constness" (which we promise to honor):
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- return iter.findNext(testFun, a);
- }
-
- template <class T> RWBoolean
- RWTValDlist<T>::contains(T val) const
- {
- // Construct an iterator, casting away "constness" (which we promise to honor):
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- return iter.findNext(val);
- }
-
- template <class T> RWBoolean
- RWTValDlist<T>::find(T val, T& k) const
- {
- // Construct an iterator, casting away "constness" (which we promise to honor):
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- RWBoolean ret = iter.findNext(val);
- if (ret) k = iter.key();
- return ret;
- }
-
- template <class T> RWBoolean
- RWTValDlist<T>::find(RWBoolean (*testFun)(T, void*), void* a, T& k) const
- {
- // Construct an iterator, casting away "constness" (which we promise to honor):
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- RWBoolean ret = iter.findNext(testFun, a);
- if (ret) k = iter.key();
- return ret;
- }
-
- template <class T> int
- RWTValDlist<T>::index(T a) const
- {
- return BASE::index(eqTestFun, &a);
- }
-
- template <class T> int
- RWTValDlist<T>::index(RWBoolean (*testFun)(T, void*), void* a) const
- {
- RWTValTester<T> capsule(testFun, a);
- return BASE::index(valTestFun, &capsule);
- }
-
- template <class T> unsigned
- RWTValDlist<T>::occurrencesOf(T val) const
- {
- unsigned count = 0;
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- while ( iter.findNext(val) ) count++;
- return count;
- }
-
- template <class T> unsigned
- RWTValDlist<T>::occurrencesOf(RWBoolean (*testFun)(T, void*), void* a) const
- {
- unsigned count = 0;
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- while ( iter.findNext(testFun, a) ) count++;
- return count;
- }
-
- template <class T> RWBoolean
- RWTValDlist<T>::remove(T val)
- {
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- return iter.removeNext(val);
- }
-
- template <class T> RWBoolean
- RWTValDlist<T>::remove(RWBoolean (*testFun)(T, void*), void* a)
- {
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- return iter.removeNext(testFun, a);
- }
-
- template <class T> unsigned
- RWTValDlist<T>::removeAll(T val)
- {
- unsigned count = 0;
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- while (iter.removeNext(val)) ++count;
- return count;
- }
-
- template <class T> unsigned
- RWTValDlist<T>::removeAll(RWBoolean (*testFun)(T, void*), void* a)
- {
- unsigned count = 0;
- RWTValDlistIterator<T> iter(*(RWTValDlist<T>*)this);
- while (iter.removeNext(testFun, a)) ++count;
- return count;
- }
-
- /****************************************************************
- * *
- * RWTValDlist<T> protected functions *
- * *
- ****************************************************************/
-
- /*
- * Extracts the value out of a link then throws the link away:
- */
- template <class T> T
- RWTValDlist<T>::peel(RWTValDlink<T>* link)
- {
- RWPRECONDITION(("RWTValDlist<T>::peel(RWTValDlink<T>*): nil link", link));
- T ret = link->_info;
- delete link;
- return ret;
- }
-
- /****************************************************************
- * *
- * Definitions for RWTValDlistIterator<T> *
- * *
- ****************************************************************/
-
- template <class T> RWBoolean
- RWTValDlistIterator<T>::findNext(T target)
- {
- while ( ++(*this) ){
- if (key()==target) return TRUE;
- }
- return FALSE;
- }
-
- template <class T> RWBoolean
- RWTValDlistIterator<T>::findNext(RWBoolean (*testFun)(T, void*), void* a)
- {
- RWTValTester<T> capsule(testFun, a);
- return BASE::findNext(RWTValDlist<T>::valTestFun, &capsule) != rwnil;
- }
-
- template <class T> RWBoolean
- RWTValDlistIterator<T>::remove()
- {
- LINK* link = BASE::remove();
- return link ? (delete link, TRUE) : FALSE;
- }
-
- template <class T> RWBoolean
- RWTValDlistIterator<T>::removeNext(T target)
- {
- while (++(*this)) {
- if (key()==target) return remove();
- }
- return FALSE;
- }
-
- template <class T> RWBoolean
- RWTValDlistIterator<T>::removeNext(RWBoolean (*testFun)(T, void*), void* a)
- {
- RWTValTester<T> capsule(testFun, a);
- LINK* link = BASE::removeNext(LIST::valTestFun, &capsule);
- return link ? (delete link, TRUE) : FALSE;
- }
-
-
- pragma pop_align_members();
- #endif /* __RWTVDLIST_H__ */
-