/*------------------------------------------------------------------------*/ /* */ /* DLISTIMP.H */ /* */ /* Copyright Borland International 1991 */ /* All Rights Reserved */ /* */ /*------------------------------------------------------------------------*/ #if !defined( __DLISTIMP_H ) #define __DLISTIMP_H #if !defined( __MEMMGR_H ) #include #endif // __MEMMGR_H /*------------------------------------------------------------------------*/ /* */ /* template class BI_DoubleListElement */ /* */ /* Node for templates BI_DoubleListImp and BI_IDoubleListImp */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_DoubleListImp; template class _CLASSTYPE BI_DoubleListBlockInitializer { protected: BI_DoubleListBlockInitializer() { PRECONDITION( count != UINT_MAX ); if( count++ == 0 ) BI_DoubleListElement::mgr = new MemBlocks( sizeof(BI_DoubleListElement), 20 ); } ~BI_DoubleListBlockInitializer() { PRECONDITION( count != 0 ); if( --count == 0 ) { delete BI_DoubleListElement::mgr; BI_DoubleListElement::mgr = 0; } } static unsigned count; }; template unsigned BI_DoubleListBlockInitializer::count = 0; template class _CLASSTYPE BI_DoubleListElement { public: BI_DoubleListElement( T t, BI_DoubleListElement _FAR *p ) : data(t) { next = p->next; prev = p; p->next = this; next->prev = this; } BI_DoubleListElement(); BI_DoubleListElement _FAR *next; BI_DoubleListElement _FAR *prev; T data; void _FAR *operator new( size_t sz ); void operator delete( void _FAR * ); private: friend class BI_DoubleListBlockInitializer; static MemBlocks _FAR *mgr; }; template MemBlocks _FAR *BI_DoubleListElement::mgr = 0; template inline BI_DoubleListElement::BI_DoubleListElement() { next = prev = 0; } template void _FAR *BI_DoubleListElement::operator new( size_t sz ) { PRECONDITION( mgr != 0 ); return mgr->allocate( sz ); } template void BI_DoubleListElement::operator delete( void _FAR *b ) { PRECONDITION( mgr != 0 ); mgr->free( b ); } inline BI_DoubleListElement::BI_DoubleListElement() { next = prev = 0; data = 0; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_DoubleListImp */ /* */ /* Implements a double-linked list of objects of type T. Assumes that */ /* T has meaningful copy semantics and a default constructor. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_DoubleListIteratorImp; template class _CLASSTYPE BI_DoubleListImp : private BI_DoubleListBlockInitializer { public: friend class BI_DoubleListIteratorImp; BI_DoubleListImp() { initList(); } ~BI_DoubleListImp() { flush(); } T peekHead() const { return head.next->data; } T peekTail() const { return tail.prev->data; } void add( T ); void addAtTail( T ); void detach( T, int = 0 ); void flush( int = 0 ); int isEmpty() const { return head.next == &tail; } void forEach( void (_FAR *)(T _FAR &, void _FAR *), void _FAR * ); T _FAR *firstThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR * ) const; T _FAR *lastThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR * ) const; protected: BI_DoubleListElement head, tail; virtual BI_DoubleListElement _FAR *findDetach( T t ) { return findPred(t); } virtual BI_DoubleListElement _FAR *findPred( T ); private: virtual void removeData( BI_DoubleListElement _FAR * ) { } void initList(); }; template void BI_DoubleListImp::initList() { head.next = &tail; head.prev = &head; tail.prev = &head; tail.next = &tail; } template void BI_DoubleListImp::add( T toAdd ) { new BI_DoubleListElement( toAdd, &head ); } template BI_DoubleListElement _FAR *BI_DoubleListImp::findPred( T t ) { tail.data = t; BI_DoubleListElement _FAR *cursor = &head; while( t != cursor->next->data ) cursor = cursor->next; return cursor; } template void BI_DoubleListImp::addAtTail( T toAdd ) { new BI_DoubleListElement( toAdd, tail.prev ); } template void BI_DoubleListImp::detach( T toDetach, int del ) { BI_DoubleListElement _FAR *pred = findDetach( toDetach ); BI_DoubleListElement _FAR *item = pred->next; if( item != &tail ) { pred->next = pred->next->next; pred->next->prev = pred; if( del != 0 ) removeData( item ); delete item; } } template void BI_DoubleListImp::flush( int del ) { BI_DoubleListElement _FAR *current = head.next; while( current != &tail ) { BI_DoubleListElement _FAR *temp = current; current = current->next; if( del != 0 ) removeData( temp ); delete temp; } initList(); } template void BI_DoubleListImp::forEach( void (_FAR *f)(T _FAR &, void _FAR *), void _FAR *args ) { BI_DoubleListElement _FAR *cur = head.next; while( cur->next != cur ) { f( cur->data, args ); cur = cur->next; } } template T _FAR *BI_DoubleListImp::firstThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { BI_DoubleListElement _FAR *cur = head.next; while( cur->next != cur ) if( cond( cur->data, args ) != 0 ) return &(cur->data); else cur = cur->next; return 0; } template T _FAR *BI_DoubleListImp::lastThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { T _FAR *res = 0; BI_DoubleListElement _FAR *cur = head.next; while( cur->next != cur ) { if( cond( cur->data, args ) != 0 ) res = &(cur->data); cur = cur->next; } return res; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_SDoubleListImp */ /* */ /* Implements a sorted double-linked list of objects of type T. */ /* Assumes that T has meaningful copy semantics, a meaningful */ /* < operator, and a default constructor. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_SDoubleListImp : public BI_DoubleListImp { public: void add( T ); protected: virtual BI_DoubleListElement _FAR *findDetach( T ); virtual BI_DoubleListElement _FAR *findPred( T ); }; template void BI_SDoubleListImp::add( T t ) { new BI_DoubleListElement( t, findPred(t) ); } template BI_DoubleListElement _FAR *BI_SDoubleListImp::findDetach( T t ) { BI_DoubleListElement _FAR *res = findPred(t); if( res->next->data == t ) return res; else return &tail; } template BI_DoubleListElement _FAR *BI_SDoubleListImp::findPred( T t ) { tail.data = t; BI_DoubleListElement _FAR *cursor = &head; while( cursor->next->data < t ) cursor = cursor->next; return cursor; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_DoubleListIteratorImp */ /* */ /* Implements a double list iterator. This iterator works with any */ /* direct double list. For indirect lists, see */ /* BI_IDoubleListIteratorImp. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_DoubleListIteratorImp { public: BI_DoubleListIteratorImp( const BI_DoubleListImp _FAR &l ) { list = &l; cur = list->head.next; } operator int() { return cur != &(list->tail); } T current() { return cur->data; } T operator ++ ( int ) { BI_DoubleListElement _FAR *temp = cur; cur = cur->next; return temp->data; } T operator ++ () { cur = cur->next; return cur->data; } void restart() { cur = list->head.next; } private: const BI_DoubleListImp _FAR *list; BI_DoubleListElement _FAR *cur; }; /*------------------------------------------------------------------------*/ /* */ /* template class BI_InternalIDoubleListImp */ /* */ /* Implements a double-linked list of pointers to objects of type T. */ /* This is implemented through the form of BI_DoubleListImp specified by */ /* List. Since pointers always have meaningful copy semantics, */ /* this class can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_InternalIDoubleListImp : public List { public: T _FAR *peekHead() const { return (T _FAR *)head.next->data; } T _FAR *peekTail() const { return (T _FAR *)tail.prev->data; } void add( T _FAR *t ) { List::add( t ); } void addAtTail( T _FAR *t ) { List::addAtTail( t ); } void detach( T _FAR *t, int del = 0 ) { List::detach( t, del ); } void forEach( void (_FAR *)(T _FAR &, void _FAR *), void _FAR * ); T _FAR *firstThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR * ) const; T _FAR *lastThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR * ) const; protected: virtual BI_DoubleListElement _FAR*findPred( void _FAR* ) = 0; private: virtual void removeData( BI_DoubleListElement _FAR *block ) { delete (T _FAR *)(block->data); } }; template void BI_InternalIDoubleListImp::forEach( void (_FAR *f)(T _FAR &, void _FAR *), void _FAR *args ) { BI_DoubleListElement _FAR *cur = head.next; while( cur->next != cur ) { f( *(T _FAR *)cur->data, args ); cur = cur->next; } } template T _FAR *BI_InternalIDoubleListImp::firstThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { BI_DoubleListElement _FAR *cur = head.next; while( cur->next != cur ) if( cond( *(T _FAR *)(cur->data), args ) != 0 ) return (T _FAR *)cur->data; else cur = cur->next; return 0; } template T _FAR *BI_InternalIDoubleListImp::lastThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { T _FAR *res = 0; BI_DoubleListElement _FAR *cur = head.next; while( cur->next != cur ) { if( cond( *(T _FAR *)(cur->data), args ) != 0 ) res = (T _FAR *)(cur->data); cur = cur->next; } return res; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_IDoubleListImp */ /* */ /* Implements a double-linked list of pointers to objects of */ /* type T. This is implemented through the template */ /* BI_InternalIDoubleListImp. Since pointers always have meaningful */ /* copy semantics, this class can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_IDoubleListImp : public BI_InternalIDoubleListImp > { protected: virtual BI_DoubleListElement _FAR *findPred( void _FAR * ); }; template BI_DoubleListElement _FAR *BI_IDoubleListImp::findPred( void _FAR *t ) { tail.data = t; BI_DoubleListElement _FAR *cursor = &head; while( !(*(T _FAR *)t == *(T _FAR *)(cursor->next->data)) ) cursor = cursor->next; return cursor; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_ISDoubleListImp */ /* */ /* Implements a sorted double-linked list of pointers to objects of */ /* type T. This is implemented through the template */ /* BI_InternalIDoubleListImp. Since pointers always have meaningful */ /* copy semantics, this class can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_ISDoubleListImp : public BI_InternalIDoubleListImp > { protected: virtual BI_DoubleListElement _FAR *findDetach( void _FAR * ); virtual BI_DoubleListElement _FAR *findPred( void _FAR * ); }; template BI_DoubleListElement _FAR *BI_ISDoubleListImp::findDetach( void _FAR *t ) { BI_DoubleListElement _FAR *res = findPred(t); if( *(T _FAR *)(res->next->data) == *(T _FAR *)t ) return res; else return &tail; } template BI_DoubleListElement _FAR *BI_ISDoubleListImp::findPred( void _FAR *t ) { tail.data = t; BI_DoubleListElement _FAR *cursor = &head; while( *(T _FAR *)(cursor->next->data) < *(T _FAR *)t ) cursor = cursor->next; return cursor; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_IDoubleListIteratorImp */ /* */ /* Implements a double list iterator. This iterator works with any */ /* indirect double list. For direct lists, see BI_DoubleListIteratorImp.*/ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_IDoubleListIteratorImp : public BI_DoubleListIteratorImp { public: BI_IDoubleListIteratorImp( const BI_DoubleListImp _FAR &l ) : BI_DoubleListIteratorImp(l) {} T _FAR *current() { return (T _FAR *)BI_DoubleListIteratorImp::current(); } T _FAR *operator ++ (int) { return (T _FAR *)BI_DoubleListIteratorImp::operator ++ (1); } T _FAR *operator ++ () { return (T _FAR *)BI_DoubleListIteratorImp::operator ++ (); } }; #endif // __DLISTIMP_H