MOAB: Mesh Oriented datABase  (version 5.2.1)
TagCompare.hpp
Go to the documentation of this file.
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, IteratorType begin, IteratorType end,
00277                                     std::vector< EntityHandle >& results )
00278 {
00279     for( IteratorType i = begin; i != end; ++i )
00280         if( compare( i->second ) ) results.push_back( i->first );
00281 }
00282 
00283 template < class Functor, class TagMap >
00284 static inline void find_map_values( Functor compare, Range::const_iterator lower, Range::const_iterator upper,
00285                                     const TagMap& tag_map, Range& results )
00286 {
00287     Range::iterator insert = results.begin();
00288     for( ; lower != upper; ++lower )
00289     {
00290         typename TagMap::const_iterator i = tag_map.find( *lower );
00291         if( i != tag_map.end() && compare( i->second ) ) insert = results.insert( insert, *lower );
00292     }
00293 }
00294 
00295 /** Find all entities for which a tag has a specific value
00296  *\param IteratorType : an iterator that has map behavior:
00297  *                      the value of 'first' is the entity handle.
00298  *                      the value of 'second' is a pointer to the tag data.
00299  *\param ContainerType : std::vector<EntityHandle> or Range
00300  */
00301 template < class IteratorType, class ContainerType >
00302 static inline void find_tag_values_equal( const TagInfo& tag_info, const void* value, int size, IteratorType begin,
00303                                           IteratorType end, ContainerType& results )
00304 {
00305     switch( tag_info.get_data_type() )
00306     {
00307         case MB_TYPE_INTEGER:
00308             if( size == sizeof( int ) )
00309                 find_tag_values< TagOneIntEqual, IteratorType >( TagOneIntEqual( value ), begin, end, results );
00310             else
00311                 find_tag_values< TagIntsEqual, IteratorType >( TagIntsEqual( value, size ), begin, end, results );
00312             break;
00313 
00314         case MB_TYPE_DOUBLE:
00315             if( size == sizeof( double ) )
00316                 find_tag_values< TagOneDoubleEqual, IteratorType >( TagOneDoubleEqual( value ), begin, end, results );
00317             else
00318                 find_tag_values< TagDoublesEqual, IteratorType >( TagDoublesEqual( value, size ), begin, end, results );
00319             break;
00320 
00321         case MB_TYPE_HANDLE:
00322             if( size == sizeof( EntityHandle ) )
00323                 find_tag_values< TagOneHandleEqual, IteratorType >( TagOneHandleEqual( value ), begin, end, results );
00324             else
00325                 find_tag_values< TagHandlesEqual, IteratorType >( TagHandlesEqual( value, size ), begin, end, results );
00326             break;
00327 
00328         default:
00329             find_tag_values< TagBytesEqual, IteratorType >( TagBytesEqual( value, size ), begin, end, results );
00330             break;
00331     }
00332 }
00333 template < class IteratorType, class ContainerType >
00334 static inline void find_tag_varlen_values_equal( const TagInfo& tag_info, const void* value, int size,
00335                                                  IteratorType begin, IteratorType end, ContainerType& results )
00336 {
00337     switch( tag_info.get_data_type() )
00338     {
00339         case MB_TYPE_INTEGER:
00340             find_tag_values< TagVarIntsEqual, IteratorType >( TagVarIntsEqual( value, size ), begin, end, results );
00341             break;
00342         case MB_TYPE_DOUBLE:
00343             find_tag_values< TagVarDoublesEqual, IteratorType >( TagVarDoublesEqual( value, size ), begin, end,
00344                                                                  results );
00345             break;
00346         case MB_TYPE_HANDLE:
00347             find_tag_values< TagVarHandlesEqual, IteratorType >( TagVarHandlesEqual( value, size ), begin, end,
00348                                                                  results );
00349             break;
00350         default:
00351             find_tag_values< TagVarBytesEqual, IteratorType >( TagVarBytesEqual( value, size ), begin, end, results );
00352             break;
00353     }
00354 }
00355 
00356 /** Find all entities for which a tag has a specific value
00357  *\param IteratorType : an iterator that has map behavior:
00358  *                      the value of 'first' is the entity handle.
00359  *                      the value of 'second' is a pointer to the tag data.
00360  *\param ContainerType : std::vector<EntityHandle> or Range
00361  */
00362 template < class TagMap >
00363 static inline void find_map_values_equal( const TagInfo& tag_info, const void* value, int size,
00364                                           Range::const_iterator begin, Range::const_iterator end, const TagMap& tag_map,
00365                                           Range& results )
00366 {
00367     switch( tag_info.get_data_type() )
00368     {
00369         case MB_TYPE_INTEGER:
00370             if( size == sizeof( int ) )
00371                 find_map_values< TagOneIntEqual, TagMap >( TagOneIntEqual( value ), begin, end, tag_map, results );
00372             else
00373                 find_map_values< TagIntsEqual, TagMap >( TagIntsEqual( value, size ), begin, end, tag_map, results );
00374             break;
00375 
00376         case MB_TYPE_DOUBLE:
00377             if( size == sizeof( double ) )
00378                 find_map_values< TagOneDoubleEqual, TagMap >( TagOneDoubleEqual( value ), begin, end, tag_map,
00379                                                               results );
00380             else
00381                 find_map_values< TagDoublesEqual, TagMap >( TagDoublesEqual( value, size ), begin, end, tag_map,
00382                                                             results );
00383             break;
00384 
00385         case MB_TYPE_HANDLE:
00386             if( size == sizeof( EntityHandle ) )
00387                 find_map_values< TagOneHandleEqual, TagMap >( TagOneHandleEqual( value ), begin, end, tag_map,
00388                                                               results );
00389             else
00390                 find_map_values< TagHandlesEqual, TagMap >( TagHandlesEqual( value, size ), begin, end, tag_map,
00391                                                             results );
00392             break;
00393 
00394         default:
00395             find_map_values< TagBytesEqual, TagMap >( TagBytesEqual( value, size ), begin, end, tag_map, results );
00396             break;
00397     }
00398 }
00399 template < class TagMap >
00400 static inline void find_map_varlen_values_equal( const TagInfo& tag_info, const void* value, int size,
00401                                                  Range::const_iterator begin, Range::const_iterator end,
00402                                                  const TagMap& tag_map, Range& results )
00403 {
00404     switch( tag_info.get_data_type() )
00405     {
00406         case MB_TYPE_INTEGER:
00407             find_map_values< TagVarIntsEqual, TagMap >( TagVarIntsEqual( value, size ), begin, end, tag_map, results );
00408             break;
00409         case MB_TYPE_DOUBLE:
00410             find_map_values< TagVarDoublesEqual, TagMap >( TagVarDoublesEqual( value, size ), begin, end, tag_map,
00411                                                            results );
00412             break;
00413         case MB_TYPE_HANDLE:
00414             find_map_values< TagVarHandlesEqual, TagMap >( TagVarHandlesEqual( value, size ), begin, end, tag_map,
00415                                                            results );
00416             break;
00417         default:
00418             find_map_values< TagVarBytesEqual, TagMap >( TagVarBytesEqual( value, size ), begin, end, tag_map,
00419                                                          results );
00420             break;
00421     }
00422 }
00423 
00424 /** Iterator to use in find_tag_values_equal for arrays of data */
00425 class ByteArrayIterator
00426 {
00427   public:
00428     typedef std::pair< EntityHandle, const char* > data_type;
00429 
00430   private:
00431     size_t step;
00432     data_type data;
00433 
00434   public:
00435     ByteArrayIterator( EntityHandle start_handle, const void* data_array, size_t tag_size )
00436         : step( tag_size ), data( start_handle, reinterpret_cast< const char* >( data_array ) )
00437 
00438     {
00439     }
00440     ByteArrayIterator( EntityHandle start_handle, const void* data_array, const TagInfo& tag_info )
00441         : step( tag_info.get_size() == MB_VARIABLE_LENGTH ? sizeof( VarLenTag ) : tag_info.get_size() ),
00442           data( start_handle, reinterpret_cast< const char* >( data_array ) )
00443     {
00444     }
00445     bool operator==( const ByteArrayIterator& other ) const
00446     {
00447         return data.first == other.data.first;
00448     }
00449     bool operator!=( const ByteArrayIterator& other ) const
00450     {
00451         return data.first != other.data.first;
00452     }
00453     ByteArrayIterator& operator++()
00454     {
00455         ++data.first;
00456         data.second += step;
00457         return *this;
00458     }
00459     ByteArrayIterator operator++( int )
00460     {
00461         ByteArrayIterator result( *this );
00462         operator++();
00463         return result;
00464     }
00465     ByteArrayIterator& operator--()
00466     {
00467         --data.first;
00468         data.second -= step;
00469         return *this;
00470     }
00471     ByteArrayIterator operator--( int )
00472     {
00473         ByteArrayIterator result( *this );
00474         operator--();
00475         return result;
00476     }
00477     ByteArrayIterator& operator+=( size_t amt )
00478     {
00479         data.first += amt;
00480         data.second += amt * step;
00481         return *this;
00482     }
00483     ByteArrayIterator& operator-=( size_t amt )
00484     {
00485         data.first -= amt;
00486         data.second -= amt * step;
00487         return *this;
00488     }
00489     EntityHandle operator-( const ByteArrayIterator& other ) const
00490     {
00491         return data.first - other.data.first;
00492     }
00493     const data_type& operator*() const
00494     {
00495         return data;
00496     }
00497     const data_type* operator->() const
00498     {
00499         return &data;
00500     }
00501 };
00502 
00503 static inline std::pair< EntityType, EntityType > type_range( EntityType type )
00504 {
00505     if( type == MBMAXTYPE )
00506         return std::pair< EntityType, EntityType >( MBVERTEX, MBMAXTYPE );
00507     else
00508     {
00509         EntityType next = type;
00510         ++next;
00511         return std::pair< EntityType, EntityType >( type, next );
00512     }
00513 }
00514 
00515 /** Dummy container that counts insertions rather than maintaining a list of entities */
00516 class InsertCount
00517 {
00518   private:
00519     size_t mCount;
00520 
00521   public:
00522     InsertCount( size_t initial_count = 0 ) : mCount( initial_count ) {}
00523 
00524     typedef int iterator;
00525     iterator begin() const
00526     {
00527         return 0;
00528     }
00529     iterator end() const
00530     {
00531         return mCount;
00532     }
00533     iterator insert( iterator /* hint */, EntityHandle first, EntityHandle last )
00534     {
00535         mCount += last - first + 1;
00536         return end();
00537     }
00538     iterator insert( iterator /* hint */, EntityHandle /* value */ )
00539     {
00540         ++mCount;
00541         return end();
00542     }
00543 };
00544 
00545 }  // namespace moab
00546 
00547 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines