ofoset.h

00001 /*
00002  *
00003  *  Copyright (C) 2002-2005, OFFIS
00004  *
00005  *  This software and supporting documentation were developed by
00006  *
00007  *    Kuratorium OFFIS e.V.
00008  *    Healthcare Information and Communication Systems
00009  *    Escherweg 2
00010  *    D-26121 Oldenburg, Germany
00011  *
00012  *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
00013  *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
00014  *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
00015  *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
00016  *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
00017  *
00018  *  Module:  ofstd
00019  *
00020  *  Author:  Thomas Wilkens
00021  *
00022  *  Purpose: Template class for administrating an ordered set of elements
00023  *           of an arbitrary type.
00024  *
00025  *  Last Update:      $Author: meichel $
00026  *  Update Date:      $Date: 2005/12/08 16:06:00 $
00027  *  Source File:      $Source: /share/dicom/cvs-depot/dcmtk/ofstd/include/dcmtk/ofstd/ofoset.h,v $
00028  *  CVS/RCS Revision: $Revision: 1.10 $
00029  *  Status:           $State: Exp $
00030  *
00031  *  CVS/RCS Log at end of file
00032  *
00033  */
00034 
00035 #ifndef OFOrderedSet_h
00036 #define OFOrderedSet_h
00037 
00038 #include "dcmtk/config/osconfig.h"
00039 #include "dcmtk/ofstd/oftypes.h"
00040 #include "dcmtk/ofstd/ofset.h"
00041 
00056 template <class T> class OFOrderedSet : public OFSet<T>
00057 {
00058   protected:
00059 
00060   public:
00063     OFOrderedSet()
00064         : OFSet<T>()
00065       {
00066       }
00067 
00068 
00072     OFOrderedSet( const OFOrderedSet<T> &src )
00073         : OFSet<T>( src )
00074       {
00075       }
00076 
00077 
00080     virtual ~OFOrderedSet()
00081       {
00082       }
00083 
00084 
00089     const OFOrderedSet<T> &operator=( const OFOrderedSet<T> &src )
00090       {
00091         return( assign( src ) );
00092       }
00093 
00094 
00098     const OFOrderedSet<T> &assign( const OFOrderedSet<T> &src )
00099       {
00100         if( this != &src )
00101           this->operator=( src );
00102 
00103         return( *this );
00104       }
00105 
00106 
00113     virtual OFBool operator==( const OFOrderedSet<T> &other ) const
00114       {
00115         // check if both sets contain the same
00116         // amount of items; if not, return OFFalse
00117         if( this->num != other.num )
00118           return( OFFalse );
00119 
00120         // initialize result with OFTrue
00121         OFBool result = OFTrue;
00122 
00123         // as long as result is OFTrue go through all items in this
00124         for( unsigned int i=0 ; i < this->num && result == OFTrue ; i++ )
00125         {
00126           // in case the current element does not equal the current
00127           // element in other, result shall be set to OFFalse
00128           if( *this->items[i] != *other.items[i] )
00129             result = OFFalse;
00130         }
00131 
00132         // return result
00133         return( result );
00134       }
00135 
00136 
00141     virtual OFBool operator!=( const OFOrderedSet<T> &other ) const
00142       {
00143         return( !( *this == other ) );
00144       }
00145 
00146 
00150     virtual void Insert( const T &item )
00151       {
00152         // if size equals num, we need more space
00153         if( this->size == this->num )
00154           Resize( this->size * 2 );
00155 
00156         // copy item
00157         T *newItem = new T( item );
00158 
00159         // insert copy into array
00160         this->items[this->num] = newItem;
00161 
00162         // increase counter
00163         this->num++;
00164       }
00165 
00166 
00170     virtual void Insert( const OFOrderedSet<T> &other )
00171       {
00172         // go through all items in other and insert each item into this
00173         for( unsigned int i=0 ; i<other.num ; i++ )
00174           Insert( *other.items[i] );
00175       }
00176 
00177 
00185     virtual void InsertAt( const T &item, unsigned int idx )
00186       {
00187         unsigned int i;
00188 
00189         // in case index is greater than the index of the last item,
00190         // insert the new item right behind the last item of the set
00191         if( idx > this->num - 1 )
00192           Insert( item );
00193         else
00194         {
00195           // if size equals num, we need more space
00196           if( this->size == this->num )
00197             Resize( this->size * 2 );
00198 
00199           // copy item
00200           T *newItem = new T( item );
00201 
00202           // create a new temporary array and assign all pointers correspondingly
00203           T **tmp = new T*[this->size];
00204 
00205           for( i=0 ; i<idx ; i++ )
00206             tmp[i] = this->items[i];
00207 
00208           tmp[idx] = newItem;
00209 
00210           for( i=idx ; i < this->size - 1 ; i++ )
00211           {
00212             if( i < this->num )
00213               tmp[i+1] = this->items[i];
00214             else
00215               tmp[i+1] = NULL;
00216           }
00217 
00218           // delete old array
00219           delete this->items;
00220 
00221           // assign new array to member variable
00222           this->items = tmp;
00223 
00224           // increase counter
00225           this->num++;
00226         }
00227       }
00228 
00229 
00233     virtual void Remove( const T &item )
00234       {
00235         // so far, nothing was deleted
00236         OFBool itemDeleted = OFFalse;
00237 
00238         // go through all items
00239         for( unsigned int i=0 ; i < this->num && !itemDeleted ; i++ )
00240         {
00241           // if current item is the one which shall be deleted
00242           if( *this->items[i] == item )
00243           {
00244             // delete item
00245             delete this->items[i];
00246 
00247             // and - so that there are no holes in the array - move all elements
00248             // behind the current element up one array field; only do so in case
00249             // we did _not_ delete the last item
00250             if( i != this->num - 1 )
00251             {
00252               unsigned int j;
00253               for( j=i+1 ; j < this->num ; j++ )
00254               {
00255                 this->items[j-1] = this->items[j];
00256               }
00257 
00258               this->items[j-1] = NULL;
00259             }
00260             else
00261               this->items[i] = NULL;
00262 
00263             // reduce counter
00264             this->num--;
00265 
00266             // remember that an item was deleted (so that always only one item will be deleted)
00267             itemDeleted = OFTrue;
00268           }
00269         }
00270       }
00271 
00272 
00276     virtual void RemoveByIndex( unsigned int idx )
00277       {
00278         // do something only if the given index is not out of range
00279         if( idx < this->num )
00280         {
00281           // delete item with given index
00282           delete this->items[idx];
00283 
00284           // and - so that there are no holes in the array - move all elements
00285           // behind the current element up one array field; only do so in case
00286           // we did _not_ delete the last item
00287           if( idx != this->num - 1 )
00288           {
00289             unsigned int j;
00290             for( j=idx+1 ; j < this->num ; j++ )
00291             {
00292               this->items[j-1] = this->items[j];
00293             }
00294 
00295             this->items[j-1] = NULL;
00296           }
00297           else
00298             this->items[idx] = NULL;
00299 
00300           // reduce counter
00301           this->num--;
00302         }
00303       }
00304 
00305 
00312     virtual T *Find( const T &item ) const
00313       {
00314         unsigned int i;
00315         OFBool itemFound = OFFalse;
00316 
00317         for( i=0 ; i < this->num && !itemFound ; i++ )
00318         {
00319           if( *this->items[i] == item )
00320             itemFound = OFTrue;
00321         }
00322 
00323         if( itemFound )
00324           return( this->items[i-1] );
00325         else
00326           return( NULL );
00327       }
00328 
00329 
00334     virtual OFBool Contains( const T &item ) const
00335       {
00336         OFBool itemFound = OFFalse;
00337 
00338         for( unsigned int i=0 ; i < this->num && !itemFound ; i++ )
00339         {
00340           if( *this->items[i] == item )
00341             itemFound = OFTrue;
00342         }
00343 
00344         return( itemFound );
00345       }
00346 
00347 
00354     virtual OFBool IsSupersetOf( const OFOrderedSet<T> &other ) const
00355       {
00356         // if this contains less or the same amount of items than other, return OFFalse
00357         if( this->num <= other.num )
00358           return( OFFalse );
00359 
00360         // initialize result with OFTrue
00361         OFBool result = OFTrue;
00362 
00363         // make a copy of this
00364         OFOrderedSet<T> s = *this;
00365 
00366         // as long as result is OFTrue go through all items in other
00367         for( unsigned int i=0 ; i<other.num && result == OFTrue ; i++ )
00368         {
00369           // in case s contains the current item of other
00370           if( s.Contains( *other.items[i] ) )
00371           {
00372             // remove this item from s so that it will not be
00373             // considered again in a later call to s.Contains()
00374             s.Remove( *other.items[i] );
00375           }
00376           // in case s does not contain the current item of other the result is OFFalse
00377           else
00378             result = OFFalse;
00379         }
00380 
00381         // return result
00382         return( result );
00383       }
00384 
00385 
00392     virtual OFBool IsSubsetOf( const OFOrderedSet<T> &other ) const
00393       {
00394         return( other.IsSupersetOf( *this ) );
00395       }
00396 
00397 
00404     OFOrderedSet<T> Union( const OFOrderedSet<T> &other ) const
00405       {
00406         // initialize result set
00407         OFOrderedSet<T> resultSet = *this;
00408 
00409         // insert other set into result set
00410         resultSet.Insert( other );
00411 
00412         // return result set
00413         return( resultSet );
00414       }
00415 
00416 
00423     OFOrderedSet<T> Intersection( const OFOrderedSet<T> &other ) const
00424       {
00425         // initialize result set
00426         OFOrderedSet<T> resultSet;
00427 
00428         // make a copy of other
00429         OFOrderedSet<T> s = other;
00430 
00431         // go through all items in this
00432         for( unsigned int i=0 ; i < this->num ; i++ )
00433         {
00434           // if s contains the current item
00435           if( s.Contains( *this->items[i] ) )
00436           {
00437             // insert the item into the result set
00438             resultSet.Insert( *this->items[i] );
00439 
00440             // and remove the item from s so that it will not be
00441             // considered again in a later call to s.Contains()
00442             s.Remove( *this->items[i] );
00443           }
00444         }
00445 
00446         // return result set
00447         return( resultSet );
00448       }
00449 
00450 
00457     OFOrderedSet<T> Difference( const OFOrderedSet<T> &other ) const
00458       {
00459         // initialize result set
00460         OFOrderedSet<T> resultSet;
00461 
00462         // make a copy of other
00463         OFOrderedSet<T> s = other;
00464 
00465         // go through all items in this
00466         for( unsigned int i=0 ; i < this->num ; i++ )
00467         {
00468           // if s does not contain the current item
00469           if( !s.Contains( *this->items[i] ) )
00470           {
00471             // insert the item into the result set
00472             resultSet.Insert( *this->items[i] );
00473           }
00474           else
00475           {
00476             // else remove the item from s so that it will not be
00477             // considered again in a later call to s.Contains()
00478             s.Remove( *this->items[i] );
00479           }
00480         }
00481 
00482         // return result set
00483         return( resultSet );
00484       }
00485 
00486 
00494     OFOrderedSet<T> SymmetricDifference( const OFOrderedSet<T> &other ) const
00495       {
00496         // determine s1 = this - other
00497         OFOrderedSet<T> s1 = (*this).Difference( other );
00498 
00499         // determine s2 = other - this
00500         OFOrderedSet<T> s2 = other.Difference( *this );
00501 
00502         // determine the union of s1 and s2
00503         OFOrderedSet<T> resultSet = s1.Union( s2 );
00504 
00505         // return result set
00506         return( resultSet );
00507       }
00508 };
00509 
00510 
00511 #endif
00512 
00513 /*
00514 ** CVS/RCS Log:
00515 ** $Log: ofoset.h,v $
00516 ** Revision 1.10  2005/12/08 16:06:00  meichel
00517 ** Changed include path schema for all DCMTK header files
00518 **
00519 ** Revision 1.9  2004/04/21 10:00:52  meichel
00520 ** Minor modifications for compilation with gcc 3.4.0
00521 **
00522 ** Revision 1.8  2002/12/17 17:01:33  wilkens
00523 ** Modified code again to keep Sun CC 2.0.1 happy on Solaris 2.5.1 (template
00524 ** errors).
00525 **
00526 ** Revision 1.7  2002/12/16 10:40:24  wilkens
00527 ** Removed superfluous implementation files and modified header and make files.
00528 **
00529 ** Revision 1.6  2002/12/13 12:26:50  wilkens
00530 ** Modified code to keep Sun CC 2.0.1 happy on Solaris 2.5.1 (template errors).
00531 **
00532 ** Revision 1.5  2002/12/09 13:03:55  joergr
00533 ** Renamed parameter to avoid name clash with global function index().
00534 **
00535 ** Revision 1.4  2002/07/09 18:29:45  wilkens
00536 ** Added some more functionality.
00537 **
00538 ** Revision 1.2  2002/07/02 15:41:33  wilkens
00539 ** Made some modifications to keep gcc version egcs-2.91.66 quiet.
00540 **
00541 ** Revision 1.1  2002/07/02 15:19:54  wilkens
00542 ** Added container classes OFOrderedSet and OFUnorderedSet which
00543 ** are based on the new abstract class OFSet.
00544 **
00545 **
00546 */


Generated on 20 Dec 2005 for OFFIS DCMTK Version 3.5.4 by Doxygen 1.4.5