moab
|
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