/*------------------------------------------------------------------------*/ /* */ /* DEQUES.H */ /* */ /* Copyright (c) 1991, 1994 Borland International */ /* All Rights Reserved */ /* */ /*------------------------------------------------------------------------*/ #if !defined( CLASSLIB_DEQUES_H ) #define CLASSLIB_DEQUES_H #if !defined( __CHECKS_H ) #include #endif #if !defined( CLASSLIB_DEFS_H ) #include #endif #if !defined( CLASSLIB_SHDDEL_H ) #include #endif #if !defined( CLASSLIB_VECTIMP_H ) #include #endif #if !defined( CLASSLIB_DLISTIMP_H ) #include #endif #pragma option -Vo- #if defined( BI_CLASSLIB_NO_po ) #pragma option -po- #endif /*------------------------------------------------------------------------*/ /* */ /* template class TDequeAsVectorImp */ /* */ /* Implements the fundamental dequeue operations, using a vector */ /* as the underlying implementation. The type Vect specifies the */ /* form of the vector, either a TVectorImp or a */ /* TIVectorImp. The type T specifies the type of the */ /* objects to be put in the dequeue. When using TVectorImp, */ /* T should be the same as T0. When using TIVectorImp, T */ /* should be of type pointer to T0. See TQueueAsVector and */ /* TIQueueAsVector for examples. */ /* */ /*------------------------------------------------------------------------*/ template class TDequeAsVectorImp { public: TDequeAsVectorImp( unsigned max = DEFAULT_DEQUE_SIZE ) : Data(max+1), Left(0), Right(0) { } int IsFull() const { return Right == Prev( Left ); } int IsEmpty() const { return Right == Left; } int GetItemsInContainer() const { return (Right>=Left) ? Right - Left : Data.Limit()-(Left-Right); } #if defined( BI_OLDNAMES ) int isFull() const { return IsFull(); } int isEmpty() const { return IsEmpty(); } int getItemsInContainer() const { return GetItemsInContainer(); } #endif // BI_OLDNAMES protected: Vect Data; unsigned Left; unsigned Right; unsigned Prev( unsigned index ) const { if( index == 0 ) index = Data.Limit(); return --index; } unsigned Next( unsigned index ) const { index++; if( index == Data.Limit() ) index = 0; return index; } }; /*------------------------------------------------------------------------*/ /* */ /* template class TMDequeAsVector */ /* */ /* Implements a managed dequeue of objects of type T, using a vector as */ /* the underlying implementation. */ /* */ /*------------------------------------------------------------------------*/ template class TMDequeAsVectorIterator; template class TMDequeAsVector : public TDequeAsVectorImp,T> { typedef TDequeAsVectorImp,T> Parent; public: friend TMDequeAsVectorIterator; typedef void (*IterFunc)(T&, void *); typedef int (*CondFunc)(const T&, void *); TMDequeAsVector( unsigned max = DEFAULT_DEQUE_SIZE ) : TDequeAsVectorImp,T>( max ) { } const T& PeekLeft() const { PRECONDITION( !IsEmpty() ); return Data[Left]; } const T& PeekRight() const { PRECONDITION( !IsEmpty() ); return Data[Prev(Right)]; } T GetLeft(); T GetRight(); void PutLeft( const T& ); void PutRight( const T& ); void ForEach( IterFunc iter, void *args ); T *FirstThat( CondFunc cond, void *args ) const; T *LastThat( CondFunc cond, void *args ) const; void Flush() { Left = Right = 0; } #if defined( BI_OLDNAMES ) const T& peekLeft() const { return PeekLeft(); } const T& peekRight() const { return PeekRight(); } T getLeft() { return GetLeft(); } T getRight() { return GetRight(); } void putLeft( const T& t ) { PutLeft(t); } void putRight( const T& t ) { PutRight(t); } void forEach( IterFunc iter, void *args ) { ForEach( iter, args ); } T *firstThat( CondFunc cond, void *args ) const { return FirstThat( cond, args ); } T *lastThat( CondFunc cond, void *args ) const { return LastThat( cond, args ); } void flush( TShouldDelete::DeleteType = TShouldDelete::DefDelete ) { Flush(); } #endif // BI_OLDNAMES }; template T TMDequeAsVector::GetRight() { PRECONDITION( !IsEmpty() ); Right = Prev(Right); T t = Data[Right]; Data[Right] = T(); return t; } template void TMDequeAsVector::PutRight( const T& t ) { PRECONDITION( !IsFull() ); Data[Right] = t; Right = Next(Right); } template T TMDequeAsVector::GetLeft() { PRECONDITION( !IsEmpty() ); T t = Data[Left]; Data[Left] = T(); Left = Next(Left); return t; } template void TMDequeAsVector::PutLeft( const T& t ) { PRECONDITION( !IsFull() ); Left = Prev(Left); Data[Left] = t; } template void TMDequeAsVector::ForEach( IterFunc iter, void *args ) { for( unsigned index = Left; index != Right; index=Next(index) ) iter( Data[index], args ); } template T *TMDequeAsVector::FirstThat( CondFunc cond, void *args ) const { for( unsigned index = Left; index != Right; index=Next(index) ) if( cond( Data[index], args ) ) return &Data[index]; return 0; } template T *TMDequeAsVector::LastThat( CondFunc cond, void *args ) const { T *res = 0; for( unsigned index = Left; index != Right; index=Next(index) ) if( cond( Data[index], args ) ) res = &Data[index]; return res; } #if defined( BI_OLDNAMES ) #define BI_MDequeAsVector TMDequeAsVector #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMDequeAsVectorIterator */ /* */ /* Implements an iterator for the family of Deques as Vectors. */ /* */ /*------------------------------------------------------------------------*/ template class TMDequeAsVectorIterator { public: TMDequeAsVectorIterator( const TMDequeAsVector& ); operator int(); const T& Current(); const T& operator ++ ( int ); const T& operator ++ (); void Restart(); #if defined( BI_OLDNAMES ) const T& current() { return Current(); } void restart() { Restart(); } #endif // BI_OLDNAMES private: unsigned Left; unsigned Right; const TMVectorImp *Vect; TMVectorIteratorImp Iter; int Second; void NextBlock(); }; template TMDequeAsVectorIterator::TMDequeAsVectorIterator( const TMDequeAsVector& v ) : Iter( v.Data ) { Vect = &v.Data; Left = v.Left; Right = v.Right; Restart(); } template TMDequeAsVectorIterator::operator int() { return int(Iter); } template const T& TMDequeAsVectorIterator::Current() { return Iter.Current(); } template const T& TMDequeAsVectorIterator::operator ++ ( int ) { const T& temp = Iter++; NextBlock(); return temp; } template const T& TMDequeAsVectorIterator::operator ++ () { Iter++; NextBlock(); return Current(); } template void TMDequeAsVectorIterator::Restart() { if( Left <= Right ) Iter.Restart( Left, Right ); else Iter.Restart( Left, Vect->Limit() ); Second = 0; } template void TMDequeAsVectorIterator::NextBlock() { if( int(Iter) == 0 && !Second && Left > Right ) { Iter.Restart( 0, Right ); Second = 1; } } #if defined( BI_OLDNAMES ) #define BI_MDequeAsVectorIterator TMDequeAsVectorIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TDequeAsVector */ /* template class TDequeAsVectorIterator */ /* */ /* Implements a dequeue of objects of type T, using a vector as the */ /* underlying implementation and TStandardAllocator as its memory */ /* manager. */ /* */ /*------------------------------------------------------------------------*/ template class TDequeAsVector : public TMDequeAsVector { public: TDequeAsVector( unsigned max = DEFAULT_DEQUE_SIZE ) : TMDequeAsVector( max ) { } }; template class TDequeAsVectorIterator : public TMDequeAsVectorIterator { public: TDequeAsVectorIterator( const TDequeAsVector& d ) : TMDequeAsVectorIterator( d ) { } }; #if defined( BI_OLDNAMES ) #define BI_DequeAsVector TDequeAsVector #define BI_DequeAsVectorIterator TDequeAsVectorIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMIDequeAsVector */ /* */ /* Implements a managed dequeue of pointers to objects of type T, */ /* using a vector as the underlying implementation. */ /* */ /*------------------------------------------------------------------------*/ template class TMIDequeAsVectorIterator; template class TMIDequeAsVector : public TDequeAsVectorImp,T *>, public TShouldDelete { typedef TDequeAsVectorImp,T *> Parent; public: friend TMIDequeAsVectorIterator; typedef void (*IterFunc)(T&, void *); typedef int (*CondFunc)(const T &, void *); TMIDequeAsVector( unsigned sz = DEFAULT_DEQUE_SIZE ) : TDequeAsVectorImp,T *>(sz) { } ~TMIDequeAsVector() { Flush(); } T *PeekLeft() const { PRECONDITION( !IsEmpty() ); return Data[Left]; } T *PeekRight() const { PRECONDITION( !IsEmpty() ); return Data[Prev(Right)]; } T *GetLeft(); T *GetRight(); void PutLeft( T *t ); void PutRight( T *t ); void Flush( TShouldDelete::DeleteType = TShouldDelete::DefDelete ); void ForEach( IterFunc iter, void *args ); T *FirstThat( CondFunc cond, void *args ) const; T *LastThat( CondFunc cond, void *args ) const; #if defined( BI_OLDNAMES ) T *peekLeft() const { return PeekLeft(); } T *peekRight() const { return PeekRight(); } T *getLeft() { return GetLeft(); } T *getRight() { return GetRight(); } void putLeft( T *t ) { PutLeft(t); } void putRight( T *t ) { PutRight(t); } void flush( TShouldDelete::DeleteType dt = TShouldDelete::DefDelete ) { Flush( dt ); } void forEach( IterFunc iter, void *args ) { ForEach( iter, args ); } T *firstThat( CondFunc cond, void *args ) const { return FirstThat( cond, args ); } T *lastThat( CondFunc cond, void *args ) const { return LastThat( cond, args ); } #endif // BI_OLDNAMES }; template T *TMIDequeAsVector::GetRight() { PRECONDITION( !IsEmpty() ); Right = Prev(Right); T *t = Data[Right]; Data[Right] = 0; return t; } template void TMIDequeAsVector::PutRight( T *t ) { PRECONDITION( !IsFull() ); Data[Right] = t; Right = Next(Right); } template T *TMIDequeAsVector::GetLeft() { PRECONDITION( !IsEmpty() ); T *t = Data[Left]; Data[Left] = 0; Left = Next(Left); return t; } template void TMIDequeAsVector::PutLeft( T *t ) { PRECONDITION( !IsFull() ); Left = Prev(Left); Data[Left] = t; } template void TMIDequeAsVector::Flush( TShouldDelete::DeleteType dt ) { if( DelObj(dt) != 0 ) { if( Left <= Right ) Data.Flush( 1, Right, Left ); else { Data.Flush( 1, Data.Limit(), Left ); Data.Flush( 1, Right, 0 ); } } Left = Right = 0; } template void TMIDequeAsVector::ForEach( IterFunc iter, void *args ) { for( unsigned index = Left; index != Right; index=Next(index) ) iter( *(Data[index]), args ); } template T *TMIDequeAsVector::FirstThat( CondFunc cond, void *args ) const { for( unsigned index = Left; index != Right; index=Next(index) ) if( cond( *(Data[index]), args ) ) return Data[index]; return 0; } template T *TMIDequeAsVector::LastThat( CondFunc cond, void *args ) const { T *res = 0; for( unsigned index = Left; index != Right; index=Next(index) ) if( cond( *(Data[index]), args ) ) res = Data[index]; return res; } #if defined( BI_OLDNAMES ) #define BI_MIDequeAsVector TMIDequeAsVector #define BI_MIDequeAsVectorIterator TMIDequeAsVectorIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TMIDequeAsVectorIterator */ /* */ /* Implements an iterator for the family of indirect Deques as Vectors. */ /* */ /*------------------------------------------------------------------------*/ template class TMIDequeAsVectorIterator { public: TMIDequeAsVectorIterator( const TMIDequeAsVector& ); operator int(); T *Current(); T *operator ++ ( int ); T *operator ++ (); void Restart(); #if defined( BI_OLDNAMES ) T *current() { return Current(); } void restart() { Restart(); } #endif // BI_OLDNAMES private: unsigned Left; unsigned Right; const TMIVectorImp *Vect; TMIVectorIteratorImp Iter; int Second; void NextBlock(); }; template TMIDequeAsVectorIterator::TMIDequeAsVectorIterator( const TMIDequeAsVector& v ) : Iter( v.Data ) { Vect = &v.Data; Left = v.Left; Right = v.Right; Restart(); } template TMIDequeAsVectorIterator::operator int() { return int(Iter); } template T *TMIDequeAsVectorIterator::Current() { return Iter.Current(); } template T *TMIDequeAsVectorIterator::operator ++ ( int ) { T *temp = Iter++; NextBlock(); return temp; } template T *TMIDequeAsVectorIterator::operator ++ () { Iter++; NextBlock(); return Iter.Current(); } template void TMIDequeAsVectorIterator::Restart() { if( Left <= Right ) Iter.Restart( Left, Right ); else Iter.Restart( Left, Vect->Limit() ); Second = 0; } template void TMIDequeAsVectorIterator::NextBlock() { if( int(Iter) == 0 && !Second && Left > Right ) { Iter.Restart( 0, Right ); Second = 1; } } /*------------------------------------------------------------------------*/ /* */ /* template class TIDequeAsVector */ /* template class TIDequeAsVectorIterator */ /* */ /* Implements a dequeue of pointers to objects of type T, using a vector */ /* as the underlying implementation and TStandardAllocator as its */ /* memory manager. */ /* */ /*------------------------------------------------------------------------*/ template class TIDequeAsVector : public TMIDequeAsVector { public: TIDequeAsVector( unsigned sz = DEFAULT_DEQUE_SIZE ) : TMIDequeAsVector(sz) { } }; template class TIDequeAsVectorIterator : public TMIDequeAsVectorIterator { public: TIDequeAsVectorIterator( const TIDequeAsVector& d ) : TMIDequeAsVectorIterator(d) { } }; #if defined( BI_OLDNAMES ) #define BI_IDequeAsVector TIDequeAsVector #define BI_IDequeAsVectorIterator TIDequeAsVectorIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TDequeAsDoubleListImp */ /* */ /* Implements the fundamental dequeue operations, using a list */ /* as the underlying implementation. The type Lst specifies the */ /* form of the list, either a TDoubleListImp or a */ /* TIDoubleListImp. The type T specifies the type of the */ /* objects to be put in the deque. When using TDoubleListImp, */ /* T should be the same as T0. When using TIDoubleListImp, T */ /* should be of type pointer to T0. See TDequeAsDoubleList and */ /* TIDequeAsDoubleList for examples. */ /* */ /*------------------------------------------------------------------------*/ template class TDequeAsDoubleListImp { public: TDequeAsDoubleListImp() { } int IsFull() const { return 0; } int IsEmpty() const { return GetItemsInContainer() == 0; } int GetItemsInContainer() const { return Data.GetItemsInContainer(); } #if defined( BI_OLDNAMES ) int isFull() const { return IsFull(); } int isEmpty() const { return IsEmpty(); } int getItemsInContainer() const { return GetItemsInContainer(); } #endif // BI_OLDNAMES protected: Lst Data; }; /*------------------------------------------------------------------------*/ /* */ /* template class TMDequeAsDoubleList */ /* template class TMDequeAsDoubleListIterator */ /* */ /* Implements a managed dequeue of objects of type T, using a */ /* double-linked list as the underlying implementation. */ /* */ /*------------------------------------------------------------------------*/ template class TMDequeAsDoubleListIterator; template class TMDequeAsDoubleList : public TDequeAsDoubleListImp,T> { typedef TDequeAsDoubleListImp,T> Parent; public: friend TMDequeAsDoubleListIterator; typedef void (*IterFunc)(T &, void *); typedef int (*CondFunc)(const T&, void *); T GetLeft(); T GetRight(); void PutLeft( const T& t ) { Data.Add( t ); } void PutRight( const T& t ) { Data.AddAtTail( t ); } const T& PeekLeft() const { PRECONDITION( !IsEmpty() ); return Data.PeekHead(); } const T& PeekRight() const { PRECONDITION( !IsEmpty() ); return Data.PeekTail(); } void ForEach( IterFunc iter, void *args ) { Data.ForEach( iter, args ); } T *FirstThat( CondFunc cond, void *args ) const { return Data.FirstThat( cond, args ); } T *LastThat( CondFunc cond, void *args ) const { return Data.LastThat( cond, args ); } void Flush() { Data.Flush(); } #if defined( BI_OLDNAMES ) T peekLeft() const { return PeekLeft(); } T peekRight() const { return PeekRight(); } T getLeft() { return GetLeft(); } T getRight() { return GetRight(); } void putLeft( const T& t ) { PutLeft(t); } void putRight( const T& t ) { PutRight(t); } void flush( TShouldDelete::DeleteType = TShouldDelete::DefDelete ) { Flush(); } void forEach( IterFunc iter, void *args ) { ForEach( iter, args ); } T *firstThat( CondFunc cond, void *args ) const { return FirstThat( cond, args ); } T *lastThat( CondFunc cond, void *args ) const { return LastThat( cond, args ); } void flush( int ) { Flush(); } #endif // BI_OLDNAMES }; template T TMDequeAsDoubleList::GetLeft() { PRECONDITION( !IsEmpty() ); T t = Data.PeekHead(); Data.DetachAtHead(); return t; } template T TMDequeAsDoubleList::GetRight() { PRECONDITION( !IsEmpty() ); T t = Data.PeekTail(); Data.DetachAtTail(); return t; } template class TMDequeAsDoubleListIterator : public TMDoubleListIteratorImp { public: TMDequeAsDoubleListIterator( const TMDequeAsDoubleList& s ) : TMDoubleListIteratorImp(s.Data) { } }; #if defined( BI_OLDNAMES ) #define BI_MDequeAsDoubleList TMDequeAsDoubleList #define BI_MDequeAsDoubleListIterator TMDequeAsDoubleListIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TDequeAsDoubleList */ /* template class TDequeAsDoubleListIterator */ /* */ /* Implements a dequeue of objects of type T, using a double-linked list */ /* as the underlying implementation and TStandardAllocator as its */ /* memory manager. */ /* */ /*------------------------------------------------------------------------*/ template class TDequeAsDoubleList : public TMDequeAsDoubleList { }; #if defined( BI_OLDNAMES ) #define BI_DequeAsDoubleList TDequeAsDoubleList #endif template class TDequeAsDoubleListIterator : public TMDequeAsDoubleListIterator { public: TDequeAsDoubleListIterator( const TDequeAsDoubleList& s ) : TMDequeAsDoubleListIterator(s) {} }; /*------------------------------------------------------------------------*/ /* */ /* template class TMIDequeAsDoubleList */ /* template class TMIDequeAsDoubleListIterator */ /* */ /* Implements a managed dequeue of pointers to objects of type T, */ /* using a double-linked list as the underlying implementation. */ /* */ /*------------------------------------------------------------------------*/ template class TMIDequeAsDoubleListIterator; template class TMIDequeAsDoubleList : public TDequeAsDoubleListImp,T *>, public TShouldDelete { typedef TDequeAsDoubleListImp,T *> Parent; public: friend TMIDequeAsDoubleListIterator; typedef void (*IterFunc)(T&, void *); typedef int (*CondFunc)(const T&, void *); T *GetLeft(); T *GetRight(); void PutLeft( T *t ) { Data.Add( t ); } void PutRight( T *t ) { Data.AddAtTail( t ); } T *PeekLeft() const { PRECONDITION( !IsEmpty() ); return STATIC_CAST(T *,Data.PeekHead()); } T *PeekRight() const { PRECONDITION( !IsEmpty() ); return STATIC_CAST(T *,Data.PeekTail()); } void Flush( TShouldDelete::DeleteType dt = TShouldDelete::DefDelete ) { Data.Flush( DelObj(dt) ); } void ForEach( IterFunc iter, void *args ) { Data.ForEach( iter, args ); } T *FirstThat( CondFunc cond, void *args ) const { return Data.FirstThat( cond, args ); } T *LastThat( CondFunc cond, void *args ) const { return Data.LastThat( cond, args ); } #if defined( BI_OLDNAMES ) T *peekLeft() const { return PeekLeft(); } T *peekRight() const { return PeekRight(); } T *getLeft() { return GetLeft(); } T *getRight() { return GetRight(); } void putLeft( T *t ) { PutLeft(t); } void putRight( T *t ) { PutRight(t); } void flush( TShouldDelete::DeleteType dt = TShouldDelete::DefDelete ) { Flush(dt); } void forEach( IterFunc iter, void *args ) { ForEach( iter, args ); } T *firstThat( CondFunc cond, void *args ) const { return FirstThat( cond, args ); } T *lastThat( CondFunc cond, void *args ) const { return LastThat( cond, args ); } #endif // BI_OLDNAMES }; template class TMIDequeAsDoubleListIterator : public TMIDoubleListIteratorImp { public: TMIDequeAsDoubleListIterator( const TMIDequeAsDoubleList& s ) : TMIDoubleListIteratorImp(s.Data) { } }; template T *TMIDequeAsDoubleList::GetLeft() { PRECONDITION( !IsEmpty() ); T *t = Data.PeekHead(); Data.Detach( t, 0 ); return t; } template T *TMIDequeAsDoubleList::GetRight() { PRECONDITION( !IsEmpty() ); T *t = Data.PeekTail(); Data.Detach( t, 0 ); return t; } #if defined( BI_OLDNAMES ) #define BI_MIDequeAsDoubleList TMIDequeAsDoubleList #define BI_MIDequeAsDoubleListIterator TMIDequeAsDoubleListIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TIDequeAsDoubleList */ /* template class TIDequeAsDoubleListIterator */ /* */ /* Implements a dequeue of pointers to objects of type T, using a */ /* double-linked list as the underlying implementation and */ /* TStandardAllocator as its memory manager. */ /* */ /*------------------------------------------------------------------------*/ template class TIDequeAsDoubleList : public TMIDequeAsDoubleList { }; template class TIDequeAsDoubleListIterator : public TMIDequeAsDoubleListIterator { public: TIDequeAsDoubleListIterator( const TIDequeAsDoubleList& s ) : TMIDequeAsDoubleListIterator(s) {} }; #if defined( BI_OLDNAMES ) #define BI_IDequeAsDoubleList TIDequeAsDoubleList #define BI_IDequeAsDoubleListIterator TIDequeAsDoubleListIterator #endif /*------------------------------------------------------------------------*/ /* */ /* template class TDeque */ /* template class TDequeIterator */ /* */ /* Easy names for TDequeAsVector and TDequeAsVectorIterator. */ /* */ /*------------------------------------------------------------------------*/ template class TDeque : public TDequeAsVector { public: TDeque( unsigned max = DEFAULT_QUEUE_SIZE ) : TDequeAsVector( max ) { } } template class TDequeIterator : public TDequeAsVectorIterator { public: TDequeIterator( const TDeque& a ) : TDequeAsVectorIterator(a) { } }; #if defined( BI_CLASSLIB_NO_po ) #pragma option -po. #endif #pragma option -Vo. #endif // CLASSLIB_DEQUES_H