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 */