00001 /* 00002 * 00003 * Copyright (C) 1997-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 unordered set of elements 00023 * of an arbitrary type. 00024 * 00025 * Last Update: $Author: meichel $ 00026 * Update Date: $Date: 2005/12/12 09:24:27 $ 00027 * Source File: $Source: /share/dicom/cvs-depot/dcmtk/ofstd/include/dcmtk/ofstd/ofuoset.h,v $ 00028 * CVS/RCS Revision: $Revision: 1.6 $ 00029 * Status: $State: Exp $ 00030 * 00031 * CVS/RCS Log at end of file 00032 * 00033 */ 00034 00035 #ifndef OFUnorderedSet_h 00036 #define OFUnorderedSet_h 00037 00038 #include "dcmtk/config/osconfig.h" 00039 #include "dcmtk/ofstd/oftypes.h" 00040 #include "dcmtk/ofstd/ofset.h" 00041 00057 template <class T> class OFUnorderedSet : public OFSet<T> 00058 { 00059 protected: 00060 00061 public: 00064 OFUnorderedSet() 00065 : OFSet<T>() 00066 { 00067 } 00068 00069 00073 OFUnorderedSet( const OFUnorderedSet<T> &src ) 00074 : OFSet<T>( src ) 00075 { 00076 } 00077 00078 00081 virtual ~OFUnorderedSet() 00082 { 00083 } 00084 00085 00090 const OFUnorderedSet<T> &operator=( const OFUnorderedSet<T> &src ) 00091 { 00092 if( this == &src ) 00093 return( *this ); 00094 00095 OFSet<T>::operator=( src ); 00096 00097 return( *this ); 00098 } 00099 00100 00105 virtual OFBool operator==( const OFUnorderedSet<T> &other ) const 00106 { 00107 // check if both sets contain the same 00108 // amount of items; if not, return OFFalse 00109 if( OFSet<T>::num != other.num ) 00110 return( OFFalse ); 00111 00112 // initialize result with OFTrue 00113 OFBool result = OFTrue; 00114 00115 // make a copy of this 00116 OFUnorderedSet<T> s = *this; 00117 00118 // as long as result is OFTrue go through all items in other 00119 for( unsigned int i=0 ; i<other.num && result == OFTrue ; i++ ) 00120 { 00121 // in case s contains the current item of other 00122 if( s.Contains( *other.items[i] ) ) 00123 { 00124 // remove this item from s so that it will not be 00125 // considered again in a later call to s.Contains() 00126 s.Remove( *other.items[i] ); 00127 } 00128 // in case s doesn't contain the current item of other the result is OFFalse 00129 else 00130 result = OFFalse; 00131 } 00132 00133 // return result 00134 return( result ); 00135 } 00136 00137 00142 virtual OFBool operator!=( const OFUnorderedSet<T> &other ) const 00143 { 00144 return( !( *this == other ) ); 00145 } 00146 00147 00151 virtual void Insert( const T &item ) 00152 { 00153 // if size equals num, we need more space 00154 if( OFSet<T>::size == OFSet<T>::num ) 00155 Resize( OFSet<T>::size * 2 ); 00156 00157 // copy item 00158 T *newItem = new T( item ); 00159 00160 // insert copy into array 00161 OFSet<T>::items[OFSet<T>::num] = newItem; 00162 00163 // increase counter 00164 OFSet<T>::num++; 00165 } 00166 00167 00171 virtual void Insert( const OFUnorderedSet<T> &other ) 00172 { 00173 // go through all items in other and insert each item into this 00174 for( unsigned int i=0 ; i<other.num ; i++ ) 00175 Insert( *other.items[i] ); 00176 } 00177 00178 00182 virtual void Remove( const T &item ) 00183 { 00184 // so far, nothing was deleted 00185 OFBool itemDeleted = OFFalse; 00186 00187 // go through all items 00188 for( unsigned int i=0 ; i<OFSet<T>::num && !itemDeleted ; i++ ) 00189 { 00190 // if current item is the one which shall be deleted 00191 if( *OFSet<T>::items[i] == item ) 00192 { 00193 // delete item 00194 delete OFSet<T>::items[i]; 00195 00196 // and - so that there are no holes in the array - move the last 00197 // item to the array field from which the item was deleted; 00198 // only do so in case we did _not_ delete the last item 00199 if( i != OFSet<T>::num - 1 ) 00200 { 00201 OFSet<T>::items[i] = OFSet<T>::items[OFSet<T>::num-1]; 00202 OFSet<T>::items[OFSet<T>::num-1] = NULL; 00203 } 00204 else 00205 OFSet<T>::items[i] = NULL; 00206 00207 // reduce counter 00208 OFSet<T>::num--; 00209 00210 // remember that an item was deleted (so that always only one item will be deleted) 00211 itemDeleted = OFTrue; 00212 } 00213 } 00214 } 00215 00216 00220 virtual void RemoveByIndex( unsigned int index ) 00221 { 00222 // do something only if the given index is not out of range 00223 if( index < OFSet<T>::num ) 00224 { 00225 // delete item with given index 00226 delete OFSet<T>::items[index]; 00227 00228 // and - so that there are no holes in the array - move the last 00229 // item to the array field from which the item was deleted; 00230 // only do so in case we did _not_ delete the last item 00231 if( index != OFSet<T>::num - 1 ) 00232 { 00233 OFSet<T>::items[index] = OFSet<T>::items[OFSet<T>::num-1]; 00234 OFSet<T>::items[OFSet<T>::num-1] = NULL; 00235 } 00236 else 00237 OFSet<T>::items[index] = NULL; 00238 00239 // reduce counter 00240 OFSet<T>::num--; 00241 } 00242 } 00243 00244 00251 virtual T *Find( const T &item ) const 00252 { 00253 unsigned int i; 00254 OFBool itemFound = OFFalse; 00255 00256 for( i=0 ; i<OFSet<T>::num && !itemFound ; i++ ) 00257 { 00258 if( *OFSet<T>::items[i] == item ) 00259 itemFound = OFTrue; 00260 } 00261 00262 if( itemFound ) 00263 return( OFSet<T>::items[i-1] ); 00264 else 00265 return( NULL ); 00266 } 00267 00268 00273 virtual OFBool Contains( const T &item ) const 00274 { 00275 OFBool itemFound = OFFalse; 00276 00277 for( unsigned int i=0 ; i<OFSet<T>::num && !itemFound ; i++ ) 00278 { 00279 if( *OFSet<T>::items[i] == item ) 00280 itemFound = OFTrue; 00281 } 00282 00283 return( itemFound ); 00284 } 00285 00286 00293 virtual OFBool IsSupersetOf( const OFUnorderedSet<T> &other ) const 00294 { 00295 // if this contains less or the same amount of items than other, return OFFalse 00296 if( OFSet<T>::num <= other.num ) 00297 return( OFFalse ); 00298 00299 // initialize result with OFTrue 00300 OFBool result = OFTrue; 00301 00302 // make a copy of this 00303 OFUnorderedSet<T> s = *this; 00304 00305 // as long as result is OFTrue go through all items in other 00306 for( unsigned int i=0 ; i<other.num && result == OFTrue ; i++ ) 00307 { 00308 // in case s contains the current item of other 00309 if( s.Contains( *other.items[i] ) ) 00310 { 00311 // remove this item from s so that it will not be 00312 // considered again in a later call to s.Contains() 00313 s.Remove( *other.items[i] ); 00314 } 00315 // in case s does not contain the current item of other the result is OFFalse 00316 else 00317 result = OFFalse; 00318 } 00319 00320 // return result 00321 return( result ); 00322 } 00323 00324 00331 virtual OFBool IsSubsetOf( const OFUnorderedSet<T> &other ) const 00332 { 00333 return( other.IsSupersetOf( *this ) ); 00334 } 00335 00336 00343 OFUnorderedSet<T> Union( const OFUnorderedSet<T> &other ) const 00344 { 00345 // initialize result set 00346 OFUnorderedSet<T> resultSet = *this; 00347 00348 // insert other set into result set 00349 resultSet.Insert( other ); 00350 00351 // return result set 00352 return( resultSet ); 00353 } 00354 00355 00362 OFUnorderedSet<T> Intersection( const OFUnorderedSet<T> &other ) const 00363 { 00364 // initialize result set 00365 OFUnorderedSet<T> resultSet; 00366 00367 // make a copy of other 00368 OFUnorderedSet<T> s = other; 00369 00370 // go through all items in this 00371 for( unsigned int i=0 ; i< OFSet<T>::num ; i++ ) 00372 { 00373 // if s contains the current item 00374 if( s.Contains( *OFSet<T>::items[i] ) ) 00375 { 00376 // insert the item into the result set 00377 resultSet.Insert( *OFSet<T>::items[i] ); 00378 00379 // and remove the item from s so that it will not be 00380 // considered again in a later call to s.Contains() 00381 s.Remove( *OFSet<T>::items[i] ); 00382 } 00383 } 00384 00385 // return result set 00386 return( resultSet ); 00387 } 00388 00389 00396 OFUnorderedSet<T> Difference( const OFUnorderedSet<T> &other ) const 00397 { 00398 // initialize result set 00399 OFUnorderedSet<T> resultSet; 00400 00401 // make a copy of other 00402 OFUnorderedSet<T> s = other; 00403 00404 // go through all items in this 00405 for( unsigned int i=0 ; i< OFSet<T>::num ; i++ ) 00406 { 00407 // if s does not contain the current item 00408 if( !s.Contains( *OFSet<T>::items[i] ) ) 00409 { 00410 // insert the item into the result set 00411 resultSet.Insert( *OFSet<T>::items[i] ); 00412 } 00413 else 00414 { 00415 // else remove the item from s so that it will not be 00416 // considered again in a later call to s.Contains() 00417 s.Remove( *OFSet<T>::items[i] ); 00418 } 00419 } 00420 00421 // return result set 00422 return( resultSet ); 00423 } 00424 00425 00433 OFUnorderedSet<T> SymmetricDifference( const OFUnorderedSet<T> &other ) const 00434 { 00435 // determine s1 = this - other 00436 OFUnorderedSet<T> s1 = (*this).Difference( other ); 00437 00438 // determine s2 = other - this 00439 OFUnorderedSet<T> s2 = other.Difference( *this ); 00440 00441 // determine the union of s1 and s2 00442 OFUnorderedSet<T> resultSet = s1.Union( s2 ); 00443 00444 // return result set 00445 return( resultSet ); 00446 } 00447 }; 00448 00449 #endif 00450 00451 /* 00452 ** CVS/RCS Log: 00453 ** $Log: ofuoset.h,v $ 00454 ** Revision 1.6 2005/12/12 09:24:27 meichel 00455 ** Added explicit references to parent template class, needed for 00456 ** gcc 3.4.2 (MinGW port) 00457 ** 00458 ** Revision 1.5 2005/12/08 16:06:12 meichel 00459 ** Changed include path schema for all DCMTK header files 00460 ** 00461 ** Revision 1.4 2002/12/16 10:40:25 wilkens 00462 ** Removed superfluous implementation files and modified header and make files. 00463 ** 00464 ** Revision 1.3 2002/07/09 18:29:47 wilkens 00465 ** Added some more functionality. 00466 ** 00467 ** 00468 */