moab
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 /* OPAQUE FUNCTORS */
00011 
00013 class TagBytesEqual {
00014   private:
00015     const void* value;
00016     int size;
00017   public:
00018     TagBytesEqual( const void* v, int s ) : value(v), size(s) {}
00019     bool operator()( const void* data ) const
00020       { return !memcmp(value, data, size); }
00021 };
00023 class TagBytesLess {
00024   private:
00025     const void* value;
00026     int size;
00027   public:
00028     TagBytesLess( const void* v, int s ) : value(v), size(s) {}
00029     bool operator()( const void* data ) const
00030       { return 0 < memcmp(value, data, size); }
00031 };
00033 class TagVarBytesEqual {
00034   private:
00035     const void* value;
00036     int size;
00037   public:
00038     TagVarBytesEqual( const void* v, int s ) : value(v), size(s) {}
00039     bool operator()( const void* data ) const {
00040       const VarLenTag* vdata = reinterpret_cast<const VarLenTag*>(data);
00041       return (int)vdata->size() == size && !memcmp(value, vdata->data(), size); 
00042     }
00043     bool operator()( const VarLenTag& vdata ) const {
00044       return (int)vdata.size() == size && !memcmp(value, vdata.data(), size); 
00045     }
00046 };
00048 class TagVarBytesLess {
00049   private:
00050     const void* value;
00051     int size;
00052   public:
00053     TagVarBytesLess( const void* v, int s ) : value(v), size(s) {}
00054     bool operator()( const void* data ) const {
00055       const VarLenTag* vdata = reinterpret_cast<const VarLenTag*>(data);
00056       if ((int)vdata->size() < size) 
00057         return 0 <= memcmp( vdata->data(), value, vdata->size() );
00058       else
00059         return 0 < memcmp( vdata->data(), value, size );
00060     }
00061     bool operator()( const VarLenTag& vdata ) const {
00062       if ((int)vdata.size() < size) 
00063         return 0 <= memcmp( vdata.data(), value, vdata.size() );
00064       else
00065         return 0 < memcmp( vdata.data(), value, size );
00066     }
00067 };
00068 
00069 
00070 /* TEMPLATE FUNCTORS */
00071 
00072 
00074 template <typename T>
00075 class TagTypeEqual {
00076   private:
00077     const T* value;
00078     int size;
00079   public:
00080     TagTypeEqual( const void* v, int s ) 
00081       : value(reinterpret_cast<const T*>(v)), 
00082         size(s/sizeof(T)) 
00083         {}
00084         
00085     bool operator()( const void* data ) const { 
00086       const T* ddata = reinterpret_cast<const T*>(data);
00087       for (int i = 0; i < size; ++i)
00088         if (value[i] != ddata[i])
00089           return false;
00090       return true;
00091     }
00092 };
00093 
00095 template <typename T>
00096 class TagTypeLess {
00097   private:
00098     const T* value;
00099     int size;
00100   public:
00101     TagTypeLess( const void* v, int s ) 
00102       : value(reinterpret_cast<const T*>(v)), 
00103         size(s/sizeof(T)) 
00104         {}
00105     
00106     bool operator()( const void* data ) const {
00107       const T* ddata = reinterpret_cast<const T*>(data);
00108       for (int i = 0; i < size; ++i)
00109         if (value[i] <= ddata[i])
00110           return false;
00111       return true;
00112     }
00113 };
00114 
00118 template <typename T>
00119 class TagOneTypeEqual {
00120   private:
00121     T value;
00122     int size;
00123   public:
00124     TagOneTypeEqual( const void* v ) 
00125       : value(*reinterpret_cast<const T*>(v))
00126         {}
00127         
00128     bool operator()( const void* data ) const { 
00129       const T* ddata = reinterpret_cast<const T*>(data);
00130       return *ddata == value;
00131     }
00132 };
00133 
00137 template <typename T>
00138 class TagOneTypeLess {
00139   private:
00140     T value;
00141     int size;
00142   public:
00143     TagOneTypeLess( const void* v ) 
00144       : value(*reinterpret_cast<const T*>(v))
00145         {}
00146     
00147     bool operator()( const void* data ) const {
00148       const T* ddata = reinterpret_cast<const T*>(data);
00149       return *ddata < value;
00150     }
00151 };
00152 
00154 template <typename T>
00155 class TagVarTypeEqual
00156 {
00157   private:
00158     const T* value;
00159     int size;
00160   public:
00161     TagVarTypeEqual( const void* v, int s ) 
00162       : value(reinterpret_cast<const T*>(v)), 
00163         size(s/sizeof(T)) 
00164         {}
00165         
00166     bool operator()( const void* data ) const {
00167       const VarLenTag* vdata = reinterpret_cast<const VarLenTag*>(data);
00168       if (vdata->size() != size * sizeof(T))
00169         return false;
00170       const T* ddata = reinterpret_cast<const T*>(vdata->data());
00171       for (int i = 0; i < size; ++i)
00172         if (value[i] != ddata[i])
00173           return false;
00174       return true;
00175     }
00176         
00177     bool operator()( const VarLenTag& vdata ) const {
00178       if (vdata.size() != size * sizeof(T))
00179         return false;
00180       const T* ddata = reinterpret_cast<const T*>(vdata.data());
00181       for (int i = 0; i < size; ++i)
00182         if (value[i] != ddata[i])
00183           return false;
00184       return true;
00185     }
00186 };
00187 
00189 template <typename T>
00190 class TagVarTypeLess
00191 {
00192   private:
00193     const T* value;
00194     int size;
00195   public:
00196     TagVarTypeLess( const void* v, int s ) 
00197       : value(reinterpret_cast<const T*>(v)), 
00198         size(s/sizeof(T)) 
00199         {}
00200     bool operator()( const void* data ) const {
00201       const VarLenTag* vdata = reinterpret_cast<const VarLenTag*>(data);
00202       const T* ddata = reinterpret_cast<const T*>(vdata->data());
00203       if ((int)vdata->size() < sizeof(T)*size) {
00204         for (int i = 0; i < vdata->size()/sizeof(T); ++i)
00205           if (value[i] < ddata[i])
00206             return false;
00207       }
00208       else {
00209         for (int i = 0; i < vdata->size()/sizeof(T); ++i)
00210           if (value[i] <= ddata[i])
00211             return false;
00212       }
00213       return true;
00214     }
00215     bool operator()( const VarLenTag& vdata ) const {
00216       const T* ddata = reinterpret_cast<const T*>(vdata.data());
00217       if ((int)vdata.size() < sizeof(T)*size) {
00218         for (int i = 0; i < vdata.size()/sizeof(T); ++i)
00219           if (value[i] < ddata[i])
00220             return false;
00221       }
00222       else {
00223         for (int i = 0; i < vdata.size()/sizeof(T); ++i)
00224           if (value[i] <= ddata[i])
00225             return false;
00226       }
00227       return true;
00228     }
00229 };
00230 
00231 /* TYPE FUNCTORS */
00232 
00233 typedef TagBytesEqual        TagIntsEqual;
00234 typedef TagVarBytesEqual     TagVarIntsEqual;
00235 typedef TagTypeLess    <int> TagIntsLess;
00236 typedef TagVarTypeLess <int> TagVarIntsLess;
00237 typedef TagOneTypeEqual<int> TagOneIntEqual;
00238 typedef TagOneTypeLess <int> TagOneIntLess;
00239 
00240 typedef TagBytesEqual                   TagHandlesEqual;
00241 typedef TagVarBytesEqual                TagVarHandlesEqual;
00242 typedef TagTypeLess    <EntityHandle> TagHandlesLess;
00243 typedef TagVarTypeLess <EntityHandle> TagVarHandlesLess;
00244 typedef TagOneTypeEqual<EntityHandle> TagOneHandleEqual;
00245 typedef TagOneTypeLess <EntityHandle> TagOneHandleLess;
00246 
00247 typedef TagTypeEqual   <double> TagDoublesEqual;
00248 typedef TagVarTypeEqual<double> TagVarDoublesEqual;
00249 typedef TagTypeLess    <double> TagDoublesLess;
00250 typedef TagVarTypeLess <double> TagVarDoublesLess;
00251 typedef TagOneTypeEqual<double> TagOneDoubleEqual;
00252 typedef TagOneTypeLess <double> TagOneDoubleLess;
00253 
00254 /* SEARCHING */
00255 
00256 template <class Functor,
00257           class IteratorType>
00258 static inline
00259 void find_tag_values( Functor compare,
00260                       IteratorType begin,
00261                       IteratorType end,
00262                       Range& results )
00263 {
00264   Range::iterator insert = results.begin();
00265   for (IteratorType i = begin; i != end; ++i) 
00266     if (compare( i->second ))
00267       insert = results.insert( insert, i->first );
00268 }
00269 
00270 template <class Functor,
00271           class IteratorType>
00272 static inline
00273 void find_tag_values( Functor compare,
00274                       IteratorType begin,
00275                       IteratorType end,
00276                       std::vector<EntityHandle>& results )
00277 {
00278   for (IteratorType i = begin; i != end; ++i) 
00279     if (compare( i->second ))
00280       results.push_back( i->first );
00281 }
00282 
00283 template <class Functor,
00284           class TagMap>
00285 static inline
00286 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     typename TagMap::const_iterator i = tag_map.find( *lower );
00295     if (i != tag_map.end() && compare( i->second ))
00296       insert = results.insert( insert, *lower );
00297   }
00298 }
00299 
00306 template <class IteratorType, class ContainerType>
00307 static inline
00308 void find_tag_values_equal( const TagInfo& tag_info,
00309                             const void* value,
00310                             int size,
00311                             IteratorType begin,
00312                             IteratorType end,
00313                             ContainerType& results )
00314 {
00315   switch (tag_info.get_data_type()) {
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
00344 void find_tag_varlen_values_equal( const TagInfo& tag_info,
00345                                    const void* value,
00346                                    int size,
00347                                    IteratorType begin,
00348                                    IteratorType end,
00349                                    ContainerType& results )
00350 {
00351   switch (tag_info.get_data_type()) {
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, results );
00357       break;
00358     case MB_TYPE_HANDLE:
00359       find_tag_values<TagVarHandlesEqual,IteratorType>( TagVarHandlesEqual( value, size ), begin, end, results );
00360       break;
00361     default:
00362       find_tag_values<TagVarBytesEqual,IteratorType>( TagVarBytesEqual( value, size ), begin, end, results );
00363       break;
00364   }
00365 }
00366 
00373 template <class TagMap>
00374 static inline
00375 void find_map_values_equal( const TagInfo& tag_info,
00376                             const void* value,
00377                             int size,
00378                             Range::const_iterator begin,
00379                             Range::const_iterator end,
00380                             const TagMap& tag_map,
00381                             Range& results )
00382 {
00383   switch (tag_info.get_data_type()) {
00384     case MB_TYPE_INTEGER:
00385       if (size == sizeof(int))
00386         find_map_values<TagOneIntEqual,TagMap>( TagOneIntEqual( value ), begin, end, tag_map, results );
00387        else
00388         find_map_values<TagIntsEqual,TagMap>( TagIntsEqual( value, size ), begin, end, tag_map, results );
00389       break;
00390         
00391     case MB_TYPE_DOUBLE:
00392       if (size == sizeof(double))
00393         find_map_values<TagOneDoubleEqual,TagMap>( TagOneDoubleEqual( value ), begin, end, tag_map, results );
00394       else
00395         find_map_values<TagDoublesEqual,TagMap>( TagDoublesEqual( value, size ), begin, end, tag_map, results );
00396       break;
00397         
00398     case MB_TYPE_HANDLE:
00399       if (size == sizeof(EntityHandle))
00400         find_map_values<TagOneHandleEqual,TagMap>( TagOneHandleEqual( value ), begin, end, tag_map, results );
00401       else
00402         find_map_values<TagHandlesEqual,TagMap>( TagHandlesEqual( value, size ), begin, end, tag_map, results );
00403       break;
00404         
00405     default:
00406       find_map_values<TagBytesEqual,TagMap>( TagBytesEqual( value, size ), begin, end, tag_map, results );
00407       break;
00408   }
00409 }
00410 template <class TagMap>
00411 static inline
00412 void find_map_varlen_values_equal( const TagInfo& tag_info,
00413                                    const void* value,
00414                                    int size,
00415                                    Range::const_iterator begin,
00416                                    Range::const_iterator end,
00417                                    const TagMap& tag_map,
00418                                    Range& results )
00419 {
00420   switch (tag_info.get_data_type()) {
00421     case MB_TYPE_INTEGER:
00422       find_map_values<TagVarIntsEqual,TagMap>( TagVarIntsEqual( value, size ), begin, end, tag_map, results );
00423       break;
00424     case MB_TYPE_DOUBLE:
00425       find_map_values<TagVarDoublesEqual,TagMap>( TagVarDoublesEqual( value, size ), begin, end, tag_map, results );
00426       break;
00427     case MB_TYPE_HANDLE:
00428       find_map_values<TagVarHandlesEqual,TagMap>( TagVarHandlesEqual( value, size ), begin, end, tag_map, results );
00429       break;
00430     default:
00431       find_map_values<TagVarBytesEqual,TagMap>( TagVarBytesEqual( value, size ), begin, end, tag_map, results );
00432       break;
00433   }
00434 }
00435 
00437 class ByteArrayIterator 
00438 {
00439   public:
00440     typedef std::pair<EntityHandle, const char*> data_type;
00441   private:
00442     size_t step;
00443     data_type data;
00444   public:
00445     ByteArrayIterator( EntityHandle start_handle,
00446                        const void* data_array,
00447                        size_t tag_size )
00448       : step(tag_size),
00449         data(start_handle, reinterpret_cast<const char*>(data_array))
00450         
00451       {}
00452     ByteArrayIterator( EntityHandle start_handle,
00453                        const void* data_array,
00454                        const TagInfo& tag_info )
00455       : step(tag_info.get_size() == MB_VARIABLE_LENGTH ? sizeof(VarLenTag) : tag_info.get_size()),
00456         data(start_handle, reinterpret_cast<const char*>(data_array))
00457         {}
00458     bool operator==( const ByteArrayIterator& other ) const
00459       { return data.first == other.data.first; }
00460     bool operator!=( const ByteArrayIterator& other ) const
00461       { return data.first != other.data.first; }
00462     ByteArrayIterator& operator++()
00463       { ++data.first; data.second += step; return *this; }
00464     ByteArrayIterator operator++(int)
00465       { ByteArrayIterator result(*this); operator++(); return result; }
00466     ByteArrayIterator& operator--()
00467       { --data.first; data.second -= step; return *this; }
00468     ByteArrayIterator operator--(int)
00469       { ByteArrayIterator result(*this); operator--(); return result; }
00470     ByteArrayIterator& operator+=(size_t amt)
00471       { data.first += amt; data.second += amt*step; return *this; }
00472     ByteArrayIterator& operator-=(size_t amt)
00473       { data.first -= amt; data.second -= amt*step; return *this; }
00474     EntityHandle operator-( const ByteArrayIterator& other ) const
00475       { return data.first - other.data.first; }
00476     const data_type& operator*() const 
00477       { return data; }
00478     const data_type* operator->() const 
00479       { return &data; }
00480 };
00481 
00482 
00483 static inline
00484 std::pair<EntityType,EntityType> type_range( EntityType type )
00485 {
00486   if (type == MBMAXTYPE)
00487     return std::pair<EntityType,EntityType>(MBVERTEX,MBMAXTYPE);
00488   else {
00489     EntityType next = type; ++next;
00490     return std::pair<EntityType,EntityType>(type,next);
00491   }
00492 }
00493 
00495 class InsertCount {
00496 private:
00497   size_t mCount;
00498   
00499 public:
00500   InsertCount( size_t initial_count = 0 ) : mCount(initial_count) {}
00501 
00502   typedef int iterator;
00503   iterator begin() const { return 0; }
00504   iterator end() const { return mCount; }
00505   iterator insert( iterator /* hint */, EntityHandle first, EntityHandle last )
00506     { mCount += last - first + 1; return end(); }
00507   iterator insert( iterator /* hint */, EntityHandle /* value */)
00508     { ++mCount; return end(); }
00509 };
00510 
00511 
00512 } // namespace moab
00513 
00514 #endif
00515 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines