/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE Versions 3.13.7 * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* * Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd * * type safe singly linked list templates * * Author Jeffrey O. Hill * johill@lanl.gov * 505 665 1831 */ #ifndef tsSLListh #define tsSLListh #ifndef assert // allow use of epicsAssert.h #include #endif // // the hp compiler complains about parameterized friend // class that has not been declared without this? // template < class T > class tsSLList; template < class T > class tsSLIter; template < class T > class tsSLIterConst; // // tsSLNode // NOTE: class T must derive from tsSLNode // template class tsSLNode { public: tsSLNode (); tsSLNode < T > & operator = ( const tsSLNode < T > & ) const; private: void removeNextItem (); // removes the item after this node T *pNext; tsSLNode ( const tsSLNode < T > & ); friend class tsSLList < T >; friend class tsSLIter < T >; friend class tsSLIterConst < T >; }; // // tsSLList // NOTE: class T must derive from tsSLNode // template < class T > class tsSLList : public tsSLNode < T > { public: tsSLList (); // creates an empty list tsSLList ( tsSLList & ); void insert ( T &item, tsSLNode < T > &itemBefore ); // insert after item before void add ( T &item ); // add to the beginning of the list T * get (); // remove from the beginning of the list T * pop (); // same as get void push ( T &item ); // same as add T * first () const; void remove ( T &itemBefore ); tsSLIterConst firstIter () const; tsSLIter firstIter (); static tsSLIterConst invalidConstIter (); static tsSLIter invalidIter (); private: const tsSLList < T > & operator = ( const tsSLList < T > & ); }; // // tsSLIterConst // template < class T > class tsSLIterConst { public: tsSLIterConst (); bool valid () const; bool operator == (const tsSLIterConst &rhs) const; bool operator != (const tsSLIterConst &rhs) const; tsSLIterConst & operator = (const tsSLIterConst &); const T & operator * () const; const T * operator -> () const; tsSLIterConst & operator ++ (); tsSLIterConst operator ++ (int); const T * pointer () const; protected: const T * pEntry; tsSLIterConst ( const T *pInitialEntry ); friend class tsSLList < T >; }; // // tsSLIter // template < class T > class tsSLIter { public: tsSLIter (); bool valid () const; bool operator == (const tsSLIter &rhs) const; bool operator != (const tsSLIter &rhs) const; tsSLIter & operator = (const tsSLIter &); T & operator * () const; T * operator -> () const; tsSLIter & operator ++ (); tsSLIter operator ++ (int); T * pointer () const; private: T *pEntry; tsSLIter ( T *pInitialEntry ); friend class tsSLList < T >; }; ////////////////////////////////////////// // // tsSLNode inline member functions // ////////////////////////////////////////// // // tsSLNode::tsSLNode () // template < class T > inline tsSLNode < T > :: tsSLNode () : pNext ( 0 ) {} // // tsSLNode::tsSLNode ( const tsSLNode < T > & ) // private - not to be used - implemented to eliminate warnings // template < class T > inline tsSLNode < T > :: tsSLNode ( const tsSLNode < T > & ) { } // // tsSLNode::operator = // // when someone copies into a class deriving from this // do _not_ change the node pointers // template < class T > inline tsSLNode < T > & tsSLNode < T >::operator = ( const tsSLNode < T > & ) const { return *this; } // // removeNextItem () // // removes the item after this node // template inline void tsSLNode::removeNextItem () { T *pItem = this->pNext; if ( pItem ) { tsSLNode < T > *pNode = pItem; this->pNext = pNode->pNext; } } ////////////////////////////////////////// // // tsSLList inline member functions // ////////////////////////////////////////// // // tsSLList::tsSLList() // create an empty list // template < class T > inline tsSLList < T > :: tsSLList () { } // // tsSLList::tsSLList( tsSLList & ) // template < class T > inline tsSLList < T > :: tsSLList ( tsSLList &listIn ) { this->pNext = listIn.pNext; listIn.pNext = 0; } // // tsSLList::insert() // (itemBefore might be the list header object and therefore // will not always be of type T) // template < class T > inline void tsSLList < T > :: insert ( T &item, tsSLNode < T > &itemBefore ) { tsSLNode < T > &node = item; node.pNext = itemBefore.pNext; itemBefore.pNext = &item; } // // tsSLList::add () // template < class T > inline void tsSLList < T > :: add ( T &item ) { this->insert ( item, *this ); } // // tsSLList::get () // template < class T > inline T * tsSLList < T > :: get () { tsSLNode < T > *pThisNode = this; T *pItem = pThisNode->pNext; pThisNode->removeNextItem (); return pItem; } // // tsSLList::pop () // template < class T > inline T * tsSLList < T > :: pop () { return this->get (); } // // tsSLList::push () // template inline void tsSLList < T > :: push ( T &item ) { this->add (item); } template inline T * tsSLList < T > :: first () const { const tsSLNode < T > *pThisNode = this; return pThisNode->pNext; } template inline void tsSLList < T > :: remove ( T &itemBefore ) { tsSLNode < T > *pBeforeNode = &itemBefore; tsSLNode < T > *pAfterNode = pBeforeNode->pNext; pBeforeNode->pNext = pAfterNode->pNext; } template inline tsSLIterConst tsSLList < T > :: firstIter () const { const tsSLNode < T > *pThisNode = this; return tsSLIterConst ( pThisNode->pNext ); } template inline tsSLIter tsSLList < T > :: firstIter () { tsSLNode < T > *pThisNode = this; return tsSLIter ( pThisNode->pNext ); } template inline tsSLIterConst tsSLList < T > :: invalidConstIter () { return tsSLIterConst ( 0 ); } template inline tsSLIter tsSLList < T > :: invalidIter () { return tsSLIter ( 0 ); } ////////////////////////////////////////// // // tsSLIterConst inline member functions // ////////////////////////////////////////// template < class T > inline tsSLIterConst::tsSLIterConst ( const T *pInitialEntry ) : pEntry ( pInitialEntry ) { } template < class T > inline tsSLIterConst::tsSLIterConst () : pEntry ( 0 ) { } template < class T > inline bool tsSLIterConst::valid () const { return this->pEntry != 0; } template < class T > inline bool tsSLIterConst::operator == ( const tsSLIterConst &rhs ) const { return this->pEntry == rhs.pConstEntry; } template < class T > inline bool tsSLIterConst::operator != (const tsSLIterConst &rhs) const { return this->pEntry != rhs.pConstEntry; } template < class T > inline tsSLIterConst & tsSLIterConst::operator = ( const tsSLIterConst & rhs ) { this->pEntry = rhs.pEntry; return *this; } template < class T > inline const T & tsSLIterConst::operator * () const { return *this->pEntry; } template < class T > inline const T * tsSLIterConst::operator -> () const { return this->pEntry; } template < class T > inline tsSLIterConst & tsSLIterConst::operator ++ () // prefix ++ { const tsSLNode < T > *pCurNode = this->pEntry; this->pEntry = pCurNode->pNext; return *this; } template < class T > inline tsSLIterConst tsSLIterConst::operator ++ ( int ) // postfix ++ { const tsSLIterConst tmp = *this; const tsSLNode < T > *pCurNode = this->pEntry; this->pEntry = pCurNode->pNext; return tmp; } template inline const T * tsSLIterConst < T > :: pointer () const { return this->pEntry; } ////////////////////////////////////////// // // tsSLIter inline member functions // ////////////////////////////////////////// template < class T > inline tsSLIter::tsSLIter ( T *pInitialEntry ) : pEntry ( pInitialEntry ) { } template < class T > inline tsSLIter::tsSLIter () : pEntry ( 0 ) { } template < class T > inline bool tsSLIter::valid () const { return this->pEntry != 0; } template < class T > inline bool tsSLIter::operator == ( const tsSLIter &rhs ) const { return this->pEntry == rhs.pEntry; } template < class T > inline bool tsSLIter::operator != ( const tsSLIter &rhs ) const { return this->pEntry != rhs.pEntry; } template < class T > inline tsSLIter & tsSLIter::operator = ( const tsSLIter & rhs ) { this->pEntry = rhs.pEntry; return *this; } template < class T > inline T & tsSLIter::operator * () const { return *this->pEntry; } template < class T > inline T * tsSLIter::operator -> () const { return this->pEntry; } template < class T > inline tsSLIter & tsSLIter::operator ++ () // prefix ++ { const tsSLNode < T > *pCurNode = this->pEntry; this->pEntry = pCurNode->pNext; return *this; } template < class T > inline tsSLIter tsSLIter::operator ++ ( int ) // postfix ++ { const tsSLIter tmp = *this; const tsSLNode < T > *pCurNode = this->pEntry; this->pEntry = pCurNode->pNext; return tmp; } template inline T * tsSLIter < T > :: pointer () const { return this->pEntry; } #endif // tsSLListh