![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef TAG_COMPARE_HPP
00002 #define TAG_COMPARE_HPP
00003
00004 #include "TagInfo.hpp"
00005 #include "VarLenTag.hpp"
00006 #include
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 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 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