/*------------------------------------------------------------------------*/ /* */ /* VECTIMP.H */ /* */ /* Copyright Borland International 1991 */ /* All Rights Reserved */ /* */ /*------------------------------------------------------------------------*/ #if !defined( __VECTIMP_H ) #define __VECTIMP_H #if !defined( __CONTAIN_H ) #include #endif // __CONTAIN_H #if !defined( __LIMITS_H ) #include #endif // __LIMITS_H #if !defined( __CHECKS_H ) #include #endif // __CHECKS_H #if !defined( __STDTEMPL_H ) #include #endif // __STDTEMPL_H /*------------------------------------------------------------------------*/ /* */ /* template class BI_VectorImp */ /* */ /* Implements a vector of objects of type T. Assumes that */ /* T has meaningful copy semantics and a default constructor. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_VectorImp { public: friend class _CLASSTYPE BI_VectorIteratorImp; BI_VectorImp() : data(0), lim(0) { } BI_VectorImp( unsigned sz, unsigned = 0 ) : data( new T[sz] ), lim(sz) { } BI_VectorImp( const BI_VectorImp _FAR & ); const BI_VectorImp _FAR & operator = ( const BI_VectorImp _FAR & ); ~BI_VectorImp() { delete [] data; } T _FAR & operator [] ( unsigned index ) const { PRECONDITION( lim > 0 && data != 0 && index < lim ); return data[index]; } unsigned limit() const { return lim; } virtual unsigned top() const { return lim; } void resize( unsigned, unsigned = 0 ); void flush( unsigned = 0, unsigned = UINT_MAX, unsigned = 0 ) {} void forEach( void (_FAR *f)(T _FAR &, void _FAR *), void _FAR *args ) { forEach( f, args, 0, lim ); } void forEach( void (_FAR *)(T _FAR &, void _FAR *), void _FAR *, unsigned, unsigned ); T _FAR *firstThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR *, unsigned, unsigned ) const; T _FAR *firstThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { return firstThat( cond, args, 0, lim ); } T _FAR *lastThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR *, unsigned, unsigned ) const; T _FAR *lastThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { return lastThat( cond, args, 0, lim ); } virtual unsigned getDelta() const { return 0; } protected: T _FAR * data; unsigned lim; virtual void zero( unsigned, unsigned ) { } }; template BI_VectorImp::BI_VectorImp( const BI_VectorImp _FAR & v ) : data( new T[v.lim] ), lim(v.lim) { PRECONDITION( lim == 0 || (data != 0 && v.data != 0) ); for( unsigned i = 0; i < lim; i++ ) data[i] = v.data[i]; } template const BI_VectorImp _FAR & BI_VectorImp::operator = ( const BI_VectorImp _FAR & v ) { if( data != v.data ) { delete [] data; data = new T[v.lim]; CHECK( data != 0 ); lim = v.lim; for( unsigned i = 0; i < lim; i++ ) data[i] = v.data[i]; } return *this; } inline unsigned nextDelta( unsigned sz, unsigned delta ) { return (sz%delta) ? ((sz+delta)/delta)*delta : sz; } template void BI_VectorImp::resize( unsigned newSz, unsigned offset ) { if( newSz <= lim || getDelta() == 0 ) return; unsigned sz = lim + nextDelta( newSz - lim, getDelta() ); T _FAR *temp = new T[sz]; unsigned last = min( sz-offset, lim ); for( unsigned i = 0; i < last; i++ ) temp[i+offset] = data[i]; delete [] data; data = temp; lim = sz; zero( last+offset, sz ); } template void BI_VectorImp::forEach( void (_FAR *f)( T _FAR &, void _FAR * ), void _FAR *args, unsigned start, unsigned stop ) { for( unsigned cur = start; cur < stop; cur++ ) f( data[cur], args ); } template T _FAR *BI_VectorImp::firstThat( int (_FAR *cond)( const T _FAR &, void _FAR * ), void _FAR *args, unsigned start, unsigned stop ) const { for( unsigned cur = start; cur < stop; cur++ ) if( cond( data[cur], args ) != 0 ) return &data[cur]; return 0; } template T _FAR *BI_VectorImp::lastThat( int (_FAR *cond)( const T _FAR &, void _FAR * ), void _FAR *args, unsigned start, unsigned stop ) const { T _FAR *res = 0; for( unsigned cur = start; cur < stop; cur++ ) if( cond( data[cur], args ) != 0 ) res = &data[cur]; return res; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_CVectorImp */ /* */ /* Implements a counted vector of objects of type T. Assumes that */ /* T has meaningful copy semantics and a default constructor. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_CVectorImp : public BI_VectorImp { public: BI_CVectorImp() : count_(0), delta(0) { } BI_CVectorImp( unsigned sz, unsigned d = 0 ) : BI_VectorImp( sz ), count_(0), delta(d) { } void add( T ); void addAt( T, unsigned ); void detach( T, int = 0 ); void detach( unsigned, int = 0 ); int isEmpty() const { return count_ == 0; } void forEach( void (_FAR *f)(T _FAR &, void _FAR *), void _FAR *args ) { forEach( f, args, 0, count_ ); } void forEach( void (_FAR *func)(T _FAR &, void _FAR *), void _FAR *args, unsigned low, unsigned high ) { BI_VectorImp::forEach( func, args, low, high ); } T _FAR *firstThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { return firstThat( cond, args, 0, count_ ); } T _FAR *firstThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args, unsigned low, unsigned high ) const { return BI_VectorImp::firstThat( cond, args, low, high ); } T _FAR *lastThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { return lastThat( cond, args, 0, count_ ); } T _FAR *lastThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args, unsigned low, unsigned high ) const { return BI_VectorImp::lastThat( cond, args, low, high ); } void flush( unsigned del = 0, unsigned stop = UINT_MAX, unsigned start = 0 ) { BI_VectorImp::flush( del, stop, start ); count_ = 0; } virtual unsigned find( T ) const; virtual unsigned top() const { return count_; } unsigned count() const { return count_; } virtual unsigned getDelta() const { return delta; } protected: unsigned count_; unsigned delta; private: virtual void removeData( T ) { } }; template void BI_CVectorImp::add( T t ) { if( ++count_ > lim ) resize( count_ ); data[count_-1] = t; } template void BI_CVectorImp::addAt( T t, unsigned loc ) { if( loc >= lim ) resize( loc+1 ); data[loc] = t; } template void BI_CVectorImp::detach( T t, int del ) { detach( find(t), del ); } template void BI_CVectorImp::detach( unsigned loc, int del ) { if( loc >= lim ) return; if( del ) removeData( data[loc] ); if( loc >= count_ ) { zero( loc, loc+1 ); // removing an element that's not return; // in the counted portion } count_--; for( unsigned cur = loc; cur < count_; cur++ ) data[cur] = data[cur+1]; zero( count_, count_+1 ); } template unsigned BI_CVectorImp::find( T t ) const { if( count_ != 0 ) { for( unsigned loc = 0; loc < count_; loc++ ) if( data[loc] == t ) return loc; } return UINT_MAX; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_SVectorImp */ /* */ /* Implements a sorted vector of objects of type T. Assumes that */ /* T has meaningful copy semantics, a meaningful < operator, */ /* and a default constructor. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_SVectorImp : public BI_CVectorImp { public: BI_SVectorImp() { } BI_SVectorImp( unsigned sz, unsigned d = 0 ) : BI_CVectorImp( sz, d ) { } void add( T ); virtual unsigned find( T ) const; }; template void BI_SVectorImp::add( T t ) { unsigned loc = count_++; if( count_ > lim ) resize( count_ ); while( loc > 0 && t < data[loc-1] ) { data[loc] = data[loc-1]; loc--; } data[loc] = t; } template unsigned BI_SVectorImp::find( T t ) const { unsigned lower = 0; unsigned upper = count_-1; if( count_ != 0 ) { while( lower < upper ) { unsigned middle = (lower+upper)/2; if( data[middle] == t ) return middle; if( data[middle] < t ) lower = middle+1; else upper = middle-1; } } if( lower == upper && data[lower] == t ) return lower; else return UINT_MAX; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_VectorIteratorImp */ /* */ /* Implements a vector iterator. This iterator works with any direct */ /* vector. For indirect vectors, see BI_IVectorIteratorImp. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_VectorIteratorImp { public: BI_VectorIteratorImp( const BI_VectorImp _FAR &v ) { vect = &v; restart(0,v.limit()); } BI_VectorIteratorImp( const BI_VectorImp _FAR &v, unsigned start, unsigned stop ) { vect = &v; restart( start, stop ); } operator int() { return cur < upper; } T current() { return (cur < upper) ? (*vect)[cur] : (*vect)[upper-1]; } T operator ++ ( int ) { if( cur >= upper ) return (*vect)[upper-1]; else return (*vect)[cur++]; } T operator ++ () { if( cur < upper ) cur++; if( cur >= upper ) return (*vect)[upper-1]; else return (*vect)[cur]; } void restart() { restart(lower,upper); } void restart( unsigned start, unsigned stop ) { cur = lower = start; upper = stop; } private: const BI_VectorImp _FAR *vect; unsigned cur; unsigned lower, upper; }; /*------------------------------------------------------------------------*/ /* */ /* template class BI_InternalIVectorImp */ /* */ /* Implements a vector of pointers to objects of type T. */ /* This is implemented through the form of BI_VectorImp specified by */ /* Vect. Since pointers always have meaningful copy semantics, */ /* this class can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_InternalIVectorImp : public Vect { public: BI_InternalIVectorImp( unsigned sz, unsigned d = 0 ) : Vect( sz, d ) { zero( 0, sz ); } ~BI_InternalIVectorImp() { flush(); } T _FAR * _FAR & operator [] ( unsigned index ) { PRECONDITION( lim == 0 || data != 0 && index < lim ); return (T _FAR *)(data[index]); } T _FAR * _FAR & operator [] ( unsigned index ) const { PRECONDITION( lim > 0 && data != 0 && index < lim ); return (T _FAR *)(data[index]); } void flush( unsigned = 0, unsigned = UINT_MAX, unsigned = 0 ); void forEach( void (_FAR *f)(T _FAR &, void _FAR *), void _FAR *args ) { forEach( f, args, 0, lim ); } void forEach( void (_FAR *)(T _FAR &, void _FAR *), void _FAR *, unsigned, unsigned ); T _FAR *firstThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { return firstThat( cond, args, 0, lim ); } T _FAR *firstThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR *, unsigned, unsigned ) const; T _FAR *lastThat( int (_FAR *cond)(const T _FAR &, void _FAR *), void _FAR *args ) const { return lastThat( cond, args, 0, lim ); } T _FAR *lastThat( int (_FAR *)(const T _FAR &, void _FAR *), void _FAR *, unsigned, unsigned ) const; virtual void zero( unsigned, unsigned ); private: static void delObj( T _FAR &, void _FAR * ); }; template void BI_InternalIVectorImp::delObj( T _FAR &tRef, void _FAR * ) { delete &tRef; } template void BI_InternalIVectorImp::flush( unsigned del, unsigned upr, unsigned lwr ) { upr = min( upr, limit() ); Vect::flush( del, upr, lwr ); if( del ) forEach( delObj, 0, lwr, upr ); zero( lwr, upr ); } template void BI_InternalIVectorImp::forEach( void (_FAR *f)( T _FAR &, void _FAR * ), void _FAR *args, unsigned start, unsigned stop ) { for( unsigned cur = start; cur < stop; cur++ ) if( data[cur] != 0 ) f( *(T _FAR *)(data[cur]), args ); } template T _FAR *BI_InternalIVectorImp::firstThat( int (_FAR *cond)( const T _FAR &, void _FAR * ), void _FAR *args, unsigned start, unsigned stop ) const { for( unsigned cur = start; cur < stop; cur++ ) if( data[cur] != 0 && cond( *(T _FAR *)(data[cur]), args ) != 0 ) return (T _FAR *)data[cur]; return 0; } template T _FAR *BI_InternalIVectorImp::lastThat( int (_FAR *cond)( const T _FAR &, void _FAR * ), void _FAR *args, unsigned start, unsigned stop ) const { T _FAR *res = 0; for( unsigned cur = start; cur < stop; cur++ ) if( data[cur] != 0 && cond( *(T _FAR *)(data[cur]), args ) != 0 ) res = (T _FAR *)data[cur]; return res; } template void BI_InternalIVectorImp::zero( unsigned lwr, unsigned upr ) { for( unsigned i = lwr; i < min( limit(), upr ); i++ ) data[i] = 0; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_InternalICVectorImp */ /* */ /* Implements a counted vector of pointers to objects of type T. */ /* This is implemented through the form of BI_VectorImp specified by */ /* Vect. Since pointers always have meaningful copy semantics, */ /* this class can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_InternalICVectorImp : public BI_InternalIVectorImp { public: BI_InternalICVectorImp( unsigned sz, unsigned d = 0 ) : BI_InternalIVectorImp( sz, d ) { } void add( T _FAR *t ); unsigned find( T _FAR *t ) const { PRECONDITION( t->isSortable() ); return find( (void _FAR *)t ); } protected: virtual unsigned find( void _FAR * ) const = 0; private: virtual void removeData( void _FAR *t ) { delete (T _FAR *)t; } }; template void BI_InternalICVectorImp::add( T _FAR *t ) { while( count_ < limit() && (*this)[count_] != 0 ) count_++; Vect::add(t); } /*------------------------------------------------------------------------*/ /* */ /* template class BI_InternalISVectorImp */ /* */ /* Implements a counted vector of pointers to objects of type T. */ /* This is implemented through the form of BI_VectorImp specified by */ /* Vect. Since pointers always have meaningful copy semantics, */ /* this class can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_InternalISVectorImp : public BI_InternalICVectorImp { public: BI_InternalISVectorImp( unsigned sz, unsigned d = 0 ) : BI_InternalICVectorImp( sz, d ) { } void add( T _FAR *t ); unsigned find( T _FAR *t ) const { return BI_InternalICVectorImp::find( (void _FAR *)t ); } protected: virtual unsigned find( void _FAR * ) const = 0; }; template void BI_InternalISVectorImp::add( T _FAR *t ) { unsigned loc = count_++; if( count_ > lim ) resize( count_ ); while( loc > 0 && *t < *(T _FAR *)(*this)[loc-1] ) { (*this)[loc] = (*this)[loc-1]; loc--; } (*this)[loc] = t; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_IVectorImp */ /* */ /* Implements a vector of pointers to objects of type T. */ /* This is implemented through the template BI_InternalIVectorImp. */ /* Since pointers always have meaningful copy semantics, this class */ /* can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_IVectorImp : public BI_InternalIVectorImp > { public: BI_IVectorImp( unsigned sz ) : BI_InternalIVectorImp >(sz) { } }; /*------------------------------------------------------------------------*/ /* */ /* template class BI_ICVectorImp */ /* */ /* Implements a counted vector of pointers to objects of type T. */ /* This is implemented through the template BI_InternalICVectorImp. */ /* Since pointers always have meaningful copy semantics, this class */ /* can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_ICVectorImp : public BI_InternalICVectorImp > { public: BI_ICVectorImp( unsigned sz, unsigned d = 0 ) : BI_InternalICVectorImp >(sz) { delta = d; } unsigned find( T _FAR *t ) const { return find( (void _FAR *)t ); } protected: virtual unsigned find( void _FAR * ) const; }; template unsigned BI_ICVectorImp::find( void _FAR *t ) const { if( limit() != 0 ) { for( unsigned loc = 0; loc < limit(); loc++ ) if( data[loc] && *(const T _FAR *)(data[loc]) == *(const T _FAR *)t ) return loc; } return UINT_MAX; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_ISVectorImp */ /* */ /* Implements a sorted vector of pointers to objects of type T. */ /* This is implemented through the template BI_InternalICVectorImp. */ /* Since pointers always have meaningful copy semantics, this class */ /* can handle any type of object. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_ISVectorImp : public BI_InternalICVectorImp > { public: BI_ISVectorImp( unsigned sz, unsigned d = 0 ) : BI_InternalICVectorImp >(sz) { delta = d; } unsigned find( T _FAR *t ) const { return find( (void _FAR *)t ); } protected: virtual unsigned find( void _FAR * ) const; }; template unsigned BI_ISVectorImp::find( void _FAR *t ) const { unsigned lower = 0; unsigned upper = count_-1; if( count_ != 0 ) { while( lower < upper ) { unsigned middle = (lower+upper)/2; if( *(const T _FAR *)(data[middle]) == *(const T _FAR *)t ) return middle; if( *(const T _FAR *)(data[middle]) < *(const T _FAR *)t ) lower = middle+1; else upper = middle-1; } } if( lower == upper && *(const T _FAR*)(data[lower]) == *(const T _FAR*)t ) return lower; else return UINT_MAX; } /*------------------------------------------------------------------------*/ /* */ /* template class BI_IVectorIteratorImp */ /* */ /* Implements a vector iterator. This iterator works with any indirect */ /* vector. For direct vectors, see BI_VectorIteratorImp. */ /* */ /*------------------------------------------------------------------------*/ template class _CLASSTYPE BI_IVectorIteratorImp : public BI_VectorIteratorImp { public: BI_IVectorIteratorImp( const BI_VectorImp _FAR &v ) : BI_VectorIteratorImp(v) { bump(); } BI_IVectorIteratorImp( const BI_VectorImp _FAR &v, unsigned l, unsigned u ) : BI_VectorIteratorImp(v,l,u) { bump(); } T _FAR *current() { return (T _FAR *)BI_VectorIteratorImp::current(); } T _FAR *operator ++ ( int ); T _FAR *operator ++ (); void restart() { BI_VectorIteratorImp::restart(); bump(); } void restart( unsigned start, unsigned stop ) { BI_VectorIteratorImp::restart( start, stop ); bump(); } private: void bump(); }; template T _FAR * BI_IVectorIteratorImp::operator ++ () { BI_VectorIteratorImp::operator++(); bump(); return (T _FAR *)current(); } template T _FAR * BI_IVectorIteratorImp::operator ++ ( int ) { void *temp = current(); BI_VectorIteratorImp::operator++(1); bump(); return (T _FAR *)temp; } template void BI_IVectorIteratorImp::bump() { while( *this != 0 && current() == 0 ) BI_VectorIteratorImp::operator++(); } #endif // __VECTIMP_H