MOAB: Mesh Oriented datABase  (version 5.4.0)
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,
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines