MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #ifndef TAG_COMPARE_HPP 00002 #define TAG_COMPARE_HPP 00003 00004 #include "TagInfo.hpp" 00005 #include "VarLenTag.hpp" 00006 #include <vector> 00007 00008 namespace moab 00009 { 00010 00011 /* OPAQUE FUNCTORS */ 00012 00013 /** Test fixed-length opaque tags for equality */ 00014 class TagBytesEqual 00015 { 00016 private: 00017 const void* value; 00018 int size; 00019 00020 public: 00021 TagBytesEqual( const void* v, int s ) : value( v ), size( s ) {} 00022 bool operator()( const void* data ) const 00023 { 00024 return !memcmp( value, data, size ); 00025 } 00026 }; 00027 /** Test if fixed-length opaque tag values are less than a value */ 00028 class TagBytesLess 00029 { 00030 private: 00031 const void* value; 00032 int size; 00033 00034 public: 00035 TagBytesLess( const void* v, int s ) : value( v ), size( s ) {} 00036 bool operator()( const void* data ) const 00037 { 00038 return 0 < memcmp( value, data, size ); 00039 } 00040 }; 00041 /** Test variable-length opaque tags for equality */ 00042 class TagVarBytesEqual 00043 { 00044 private: 00045 const void* value; 00046 int size; 00047 00048 public: 00049 TagVarBytesEqual( const void* v, int s ) : value( v ), size( s ) {} 00050 bool operator()( const void* data ) const 00051 { 00052 const VarLenTag* vdata = reinterpret_cast< const VarLenTag* >( data ); 00053 return (int)vdata->size() == size && !memcmp( value, vdata->data(), size ); 00054 } 00055 bool operator()( const VarLenTag& vdata ) const 00056 { 00057 return (int)vdata.size() == size && !memcmp( value, vdata.data(), size ); 00058 } 00059 }; 00060 /** Test if variable-length opaque tag values are less than a value */ 00061 class TagVarBytesLess 00062 { 00063 private: 00064 const void* value; 00065 int size; 00066 00067 public: 00068 TagVarBytesLess( const void* v, int s ) : value( v ), size( s ) {} 00069 bool operator()( const void* data ) const 00070 { 00071 const VarLenTag* vdata = reinterpret_cast< const VarLenTag* >( data ); 00072 if( (int)vdata->size() < size ) 00073 return 0 <= memcmp( vdata->data(), value, vdata->size() ); 00074 else 00075 return 0 < memcmp( vdata->data(), value, size ); 00076 } 00077 bool operator()( const VarLenTag& vdata ) const 00078 { 00079 if( (int)vdata.size() < size ) 00080 return 0 <= memcmp( vdata.data(), value, vdata.size() ); 00081 else 00082 return 0 < memcmp( vdata.data(), value, size ); 00083 } 00084 }; 00085 00086 /* TEMPLATE FUNCTORS */ 00087 00088 /** Compare fixed-length tags containing a known data type */ 00089 template < typename T > 00090 class TagTypeEqual 00091 { 00092 private: 00093 const T* value; 00094 int size; 00095 00096 public: 00097 TagTypeEqual( const void* v, int s ) : value( reinterpret_cast< const T* >( v ) ), size( s / sizeof( T ) ) {} 00098 00099 bool operator()( const void* data ) const 00100 { 00101 const T* ddata = reinterpret_cast< const T* >( data ); 00102 for( int i = 0; i < size; ++i ) 00103 if( value[i] != ddata[i] ) return false; 00104 return true; 00105 } 00106 }; 00107 00108 /** Compare fixed-length tags containing a known data type */ 00109 template < typename T > 00110 class TagTypeLess 00111 { 00112 private: 00113 const T* value; 00114 int size; 00115 00116 public: 00117 TagTypeLess( const void* v, int s ) : value( reinterpret_cast< const T* >( v ) ), size( s / sizeof( T ) ) {} 00118 00119 bool operator()( const void* data ) const 00120 { 00121 const T* ddata = reinterpret_cast< const T* >( data ); 00122 for( int i = 0; i < size; ++i ) 00123 if( value[i] <= ddata[i] ) return false; 00124 return true; 00125 } 00126 }; 00127 00128 /** Compare single-value tags containing a known data type 00129 * Optimization of TagTypeEqual for 1-value case. 00130 */ 00131 template < typename T > 00132 class TagOneTypeEqual 00133 { 00134 private: 00135 T value; 00136 int size; 00137 00138 public: 00139 TagOneTypeEqual( const void* v ) : value( *reinterpret_cast< const T* >( v ) ), size( 0 ) {} 00140 00141 bool operator()( const void* data ) const 00142 { 00143 const T* ddata = reinterpret_cast< const T* >( data ); 00144 return *ddata == value; 00145 } 00146 }; 00147 00148 /** Compare single-value tags containing a known data type 00149 * Optimization of TagTypeLess for 1-value case. 00150 */ 00151 template < typename T > 00152 class TagOneTypeLess 00153 { 00154 private: 00155 T value; 00156 int size; 00157 00158 public: 00159 TagOneTypeLess( const void* v ) : value( *reinterpret_cast< const T* >( v ) ), size( 0 ) {} 00160 00161 bool operator()( const void* data ) const 00162 { 00163 const T* ddata = reinterpret_cast< const T* >( data ); 00164 return *ddata < value; 00165 } 00166 }; 00167 00168 /** Compare variable-length tags containing a known data type */ 00169 template < typename T > 00170 class TagVarTypeEqual 00171 { 00172 private: 00173 const T* value; 00174 int size; 00175 00176 public: 00177 TagVarTypeEqual( const void* v, int s ) : value( reinterpret_cast< const T* >( v ) ), size( s / sizeof( T ) ) {} 00178 00179 bool operator()( const void* data ) const 00180 { 00181 const VarLenTag* vdata = reinterpret_cast< const VarLenTag* >( data ); 00182 if( vdata->size() != size * sizeof( T ) ) return false; 00183 const T* ddata = reinterpret_cast< const T* >( vdata->data() ); 00184 for( int i = 0; i < size; ++i ) 00185 if( value[i] != ddata[i] ) return false; 00186 return true; 00187 } 00188 00189 bool operator()( const VarLenTag& vdata ) const 00190 { 00191 if( vdata.size() != size * sizeof( T ) ) return false; 00192 const T* ddata = reinterpret_cast< const T* >( vdata.data() ); 00193 for( int i = 0; i < size; ++i ) 00194 if( value[i] != ddata[i] ) return false; 00195 return true; 00196 } 00197 }; 00198 00199 /** Compare variable-length tags containing a known data type */ 00200 template < typename T > 00201 class TagVarTypeLess 00202 { 00203 private: 00204 const T* value; 00205 int size; 00206 00207 public: 00208 TagVarTypeLess( const void* v, int s ) : value( reinterpret_cast< const T* >( v ) ), size( s / sizeof( T ) ) {} 00209 bool operator()( const void* data ) const 00210 { 00211 const VarLenTag* vdata = reinterpret_cast< const VarLenTag* >( data ); 00212 const T* ddata = reinterpret_cast< const T* >( vdata->data() ); 00213 if( (int)vdata->size() < sizeof( T ) * size ) 00214 { 00215 for( int i = 0; i < vdata->size() / sizeof( T ); ++i ) 00216 if( value[i] < ddata[i] ) return false; 00217 } 00218 else 00219 { 00220 for( int i = 0; i < vdata->size() / sizeof( T ); ++i ) 00221 if( value[i] <= ddata[i] ) return false; 00222 } 00223 return true; 00224 } 00225 bool operator()( const VarLenTag& vdata ) const 00226 { 00227 const T* ddata = reinterpret_cast< const T* >( vdata.data() ); 00228 if( (int)vdata.size() < sizeof( T ) * size ) 00229 { 00230 for( int i = 0; i < vdata.size() / sizeof( T ); ++i ) 00231 if( value[i] < ddata[i] ) return false; 00232 } 00233 else 00234 { 00235 for( int i = 0; i < vdata.size() / sizeof( T ); ++i ) 00236 if( value[i] <= ddata[i] ) return false; 00237 } 00238 return true; 00239 } 00240 }; 00241 00242 /* TYPE FUNCTORS */ 00243 00244 typedef TagBytesEqual TagIntsEqual; 00245 typedef TagVarBytesEqual TagVarIntsEqual; 00246 typedef TagTypeLess< int > TagIntsLess; 00247 typedef TagVarTypeLess< int > TagVarIntsLess; 00248 typedef TagOneTypeEqual< int > TagOneIntEqual; 00249 typedef TagOneTypeLess< int > TagOneIntLess; 00250 00251 typedef TagBytesEqual TagHandlesEqual; 00252 typedef TagVarBytesEqual TagVarHandlesEqual; 00253 typedef TagTypeLess< EntityHandle > TagHandlesLess; 00254 typedef TagVarTypeLess< EntityHandle > TagVarHandlesLess; 00255 typedef TagOneTypeEqual< EntityHandle > TagOneHandleEqual; 00256 typedef TagOneTypeLess< EntityHandle > TagOneHandleLess; 00257 00258 typedef TagTypeEqual< double > TagDoublesEqual; 00259 typedef TagVarTypeEqual< double > TagVarDoublesEqual; 00260 typedef TagTypeLess< double > TagDoublesLess; 00261 typedef TagVarTypeLess< double > TagVarDoublesLess; 00262 typedef TagOneTypeEqual< double > TagOneDoubleEqual; 00263 typedef TagOneTypeLess< double > TagOneDoubleLess; 00264 00265 /* SEARCHING */ 00266 00267 template < class Functor, class IteratorType > 00268 static inline void find_tag_values( Functor compare, IteratorType begin, IteratorType end, Range& results ) 00269 { 00270 Range::iterator insert = results.begin(); 00271 for( IteratorType i = begin; i != end; ++i ) 00272 if( compare( i->second ) ) insert = results.insert( insert, i->first ); 00273 } 00274 00275 template < class Functor, class IteratorType > 00276 static inline void find_tag_values( Functor compare, 00277 IteratorType begin, 00278 IteratorType end, 00279 std::vector< EntityHandle >& results ) 00280 { 00281 for( IteratorType i = begin; i != end; ++i ) 00282 if( compare( i->second ) ) results.push_back( i->first ); 00283 } 00284 00285 template < class Functor, class TagMap > 00286 static inline void find_map_values( Functor compare, 00287 Range::const_iterator lower, 00288 Range::const_iterator upper, 00289 const TagMap& tag_map, 00290 Range& results ) 00291 { 00292 Range::iterator insert = results.begin(); 00293 for( ; lower != upper; ++lower ) 00294 { 00295 typename TagMap::const_iterator i = tag_map.find( *lower ); 00296 if( i != tag_map.end() && compare( i->second ) ) insert = results.insert( insert, *lower ); 00297 } 00298 } 00299 00300 /** Find all entities for which a tag has a specific value 00301 *\param IteratorType : an iterator that has map behavior: 00302 * the value of 'first' is the entity handle. 00303 * the value of 'second' is a pointer to the tag data. 00304 *\param ContainerType : std::vector<EntityHandle> or Range 00305 */ 00306 template < class IteratorType, class ContainerType > 00307 static inline void find_tag_values_equal( const TagInfo& tag_info, 00308 const void* value, 00309 int size, 00310 IteratorType begin, 00311 IteratorType end, 00312 ContainerType& results ) 00313 { 00314 switch( tag_info.get_data_type() ) 00315 { 00316 case MB_TYPE_INTEGER: 00317 if( size == sizeof( int ) ) 00318 find_tag_values< TagOneIntEqual, IteratorType >( TagOneIntEqual( value ), begin, end, results ); 00319 else 00320 find_tag_values< TagIntsEqual, IteratorType >( TagIntsEqual( value, size ), begin, end, results ); 00321 break; 00322 00323 case MB_TYPE_DOUBLE: 00324 if( size == sizeof( double ) ) 00325 find_tag_values< TagOneDoubleEqual, IteratorType >( TagOneDoubleEqual( value ), begin, end, results ); 00326 else 00327 find_tag_values< TagDoublesEqual, IteratorType >( TagDoublesEqual( value, size ), begin, end, results ); 00328 break; 00329 00330 case MB_TYPE_HANDLE: 00331 if( size == sizeof( EntityHandle ) ) 00332 find_tag_values< TagOneHandleEqual, IteratorType >( TagOneHandleEqual( value ), begin, end, results ); 00333 else 00334 find_tag_values< TagHandlesEqual, IteratorType >( TagHandlesEqual( value, size ), begin, end, results ); 00335 break; 00336 00337 default: 00338 find_tag_values< TagBytesEqual, IteratorType >( TagBytesEqual( value, size ), begin, end, results ); 00339 break; 00340 } 00341 } 00342 template < class IteratorType, class ContainerType > 00343 static inline void find_tag_varlen_values_equal( const TagInfo& tag_info, 00344 const void* value, 00345 int size, 00346 IteratorType begin, 00347 IteratorType end, 00348 ContainerType& results ) 00349 { 00350 switch( tag_info.get_data_type() ) 00351 { 00352 case MB_TYPE_INTEGER: 00353 find_tag_values< TagVarIntsEqual, IteratorType >( TagVarIntsEqual( value, size ), begin, end, results ); 00354 break; 00355 case MB_TYPE_DOUBLE: 00356 find_tag_values< TagVarDoublesEqual, IteratorType >( TagVarDoublesEqual( value, size ), begin, end, 00357 results ); 00358 break; 00359 case MB_TYPE_HANDLE: 00360 find_tag_values< TagVarHandlesEqual, IteratorType >( TagVarHandlesEqual( value, size ), begin, end, 00361 results ); 00362 break; 00363 default: 00364 find_tag_values< TagVarBytesEqual, IteratorType >( TagVarBytesEqual( value, size ), begin, end, results ); 00365 break; 00366 } 00367 } 00368 00369 /** Find all entities for which a tag has a specific value 00370 *\param IteratorType : an iterator that has map behavior: 00371 * the value of 'first' is the entity handle. 00372 * the value of 'second' is a pointer to the tag data. 00373 *\param ContainerType : std::vector<EntityHandle> or Range 00374 */ 00375 template < class TagMap > 00376 static inline void find_map_values_equal( const TagInfo& tag_info, 00377 const void* value, 00378 int size, 00379 Range::const_iterator begin, 00380 Range::const_iterator end, 00381 const TagMap& tag_map, 00382 Range& results ) 00383 { 00384 switch( tag_info.get_data_type() ) 00385 { 00386 case MB_TYPE_INTEGER: 00387 if( size == sizeof( int ) ) 00388 find_map_values< TagOneIntEqual, TagMap >( TagOneIntEqual( value ), begin, end, tag_map, results ); 00389 else 00390 find_map_values< TagIntsEqual, TagMap >( TagIntsEqual( value, size ), begin, end, tag_map, results ); 00391 break; 00392 00393 case MB_TYPE_DOUBLE: 00394 if( size == sizeof( double ) ) 00395 find_map_values< TagOneDoubleEqual, TagMap >( TagOneDoubleEqual( value ), begin, end, tag_map, 00396 results ); 00397 else 00398 find_map_values< TagDoublesEqual, TagMap >( TagDoublesEqual( value, size ), begin, end, tag_map, 00399 results ); 00400 break; 00401 00402 case MB_TYPE_HANDLE: 00403 if( size == sizeof( EntityHandle ) ) 00404 find_map_values< TagOneHandleEqual, TagMap >( TagOneHandleEqual( value ), begin, end, tag_map, 00405 results ); 00406 else 00407 find_map_values< TagHandlesEqual, TagMap >( TagHandlesEqual( value, size ), begin, end, tag_map, 00408 results ); 00409 break; 00410 00411 default: 00412 find_map_values< TagBytesEqual, TagMap >( TagBytesEqual( value, size ), begin, end, tag_map, results ); 00413 break; 00414 } 00415 } 00416 template < class TagMap > 00417 static inline void find_map_varlen_values_equal( const TagInfo& tag_info, 00418 const void* value, 00419 int size, 00420 Range::const_iterator begin, 00421 Range::const_iterator end, 00422 const TagMap& tag_map, 00423 Range& results ) 00424 { 00425 switch( tag_info.get_data_type() ) 00426 { 00427 case MB_TYPE_INTEGER: 00428 find_map_values< TagVarIntsEqual, TagMap >( TagVarIntsEqual( value, size ), begin, end, tag_map, results ); 00429 break; 00430 case MB_TYPE_DOUBLE: 00431 find_map_values< TagVarDoublesEqual, TagMap >( TagVarDoublesEqual( value, size ), begin, end, tag_map, 00432 results ); 00433 break; 00434 case MB_TYPE_HANDLE: 00435 find_map_values< TagVarHandlesEqual, TagMap >( TagVarHandlesEqual( value, size ), begin, end, tag_map, 00436 results ); 00437 break; 00438 default: 00439 find_map_values< TagVarBytesEqual, TagMap >( TagVarBytesEqual( value, size ), begin, end, tag_map, 00440 results ); 00441 break; 00442 } 00443 } 00444 00445 /** Iterator to use in find_tag_values_equal for arrays of data */ 00446 class ByteArrayIterator 00447 { 00448 public: 00449 typedef std::pair< EntityHandle, const char* > data_type; 00450 00451 private: 00452 size_t step; 00453 data_type data; 00454 00455 public: 00456 ByteArrayIterator( EntityHandle start_handle, const void* data_array, size_t tag_size ) 00457 : step( tag_size ), data( start_handle, reinterpret_cast< const char* >( data_array ) ) 00458 00459 { 00460 } 00461 ByteArrayIterator( EntityHandle start_handle, const void* data_array, const TagInfo& tag_info ) 00462 : step( tag_info.get_size() == MB_VARIABLE_LENGTH ? sizeof( VarLenTag ) : tag_info.get_size() ), 00463 data( start_handle, reinterpret_cast< const char* >( data_array ) ) 00464 { 00465 } 00466 bool operator==( const ByteArrayIterator& other ) const 00467 { 00468 return data.first == other.data.first; 00469 } 00470 bool operator!=( const ByteArrayIterator& other ) const 00471 { 00472 return data.first != other.data.first; 00473 } 00474 ByteArrayIterator& operator++() 00475 { 00476 ++data.first; 00477 data.second += step; 00478 return *this; 00479 } 00480 ByteArrayIterator operator++( int ) 00481 { 00482 ByteArrayIterator result( *this ); 00483 operator++(); 00484 return result; 00485 } 00486 ByteArrayIterator& operator--() 00487 { 00488 --data.first; 00489 data.second -= step; 00490 return *this; 00491 } 00492 ByteArrayIterator operator--( int ) 00493 { 00494 ByteArrayIterator result( *this ); 00495 operator--(); 00496 return result; 00497 } 00498 ByteArrayIterator& operator+=( size_t amt ) 00499 { 00500 data.first += amt; 00501 data.second += amt * step; 00502 return *this; 00503 } 00504 ByteArrayIterator& operator-=( size_t amt ) 00505 { 00506 data.first -= amt; 00507 data.second -= amt * step; 00508 return *this; 00509 } 00510 EntityHandle operator-( const ByteArrayIterator& other ) const 00511 { 00512 return data.first - other.data.first; 00513 } 00514 const data_type& operator*() const 00515 { 00516 return data; 00517 } 00518 const data_type* operator->() const 00519 { 00520 return &data; 00521 } 00522 }; 00523 00524 static inline std::pair< EntityType, EntityType > type_range( EntityType type ) 00525 { 00526 if( type == MBMAXTYPE ) 00527 return std::pair< EntityType, EntityType >( MBVERTEX, MBMAXTYPE ); 00528 else 00529 { 00530 EntityType next = type; 00531 ++next; 00532 return std::pair< EntityType, EntityType >( type, next ); 00533 } 00534 } 00535 00536 /** Dummy container that counts insertions rather than maintaining a list of entities */ 00537 class InsertCount 00538 { 00539 private: 00540 size_t mCount; 00541 00542 public: 00543 InsertCount( size_t initial_count = 0 ) : mCount( initial_count ) {} 00544 00545 typedef int iterator; 00546 iterator begin() const 00547 { 00548 return 0; 00549 } 00550 iterator end() const 00551 { 00552 return mCount; 00553 } 00554 iterator insert( iterator /* hint */, EntityHandle first, EntityHandle last ) 00555 { 00556 mCount += last - first + 1; 00557 return end(); 00558 } 00559 iterator insert( iterator /* hint */, EntityHandle /* value */ ) 00560 { 00561 ++mCount; 00562 return end(); 00563 } 00564 }; 00565 00566 } // namespace moab 00567 00568 #endif