MOAB: Mesh Oriented datABase  (version 5.2.1)
TagTest.cpp
Go to the documentation of this file.
00001 #include "moab/Core.hpp"
00002 #include "moab/Range.hpp"
00003 #include "TestUtil.hpp"
00004 #include <stdlib.h>
00005 #include <algorithm>
00006 
00007 using namespace moab;
00008 
00009 void test_create_tag();
00010 void test_get_set_sparse_int();
00011 void test_get_set_dense_int();
00012 void test_get_set_dense_double();
00013 void test_get_set_bit();
00014 void test_get_by_tag();
00015 void test_get_by_tag_value();
00016 void test_get_by_tag_value_dense();
00017 void test_mesh_value();
00018 void test_get_pointers_sparse();
00019 void test_get_pointers_dense();
00020 void test_set_pointers_sparse();
00021 void test_set_pointers_dense();
00022 void test_get_entity_tags();
00023 void test_delete_sparse_tag();
00024 void test_delete_dense_tag();
00025 void test_delete_mesh_tag();
00026 void test_delete_sparse_data();
00027 void test_delete_dense_data();
00028 void test_delete_bit_data();
00029 void test_create_variable_length_tag();
00030 void test_get_set_variable_length_sparse();
00031 void test_get_set_variable_length_dense();
00032 void test_get_set_variable_length_mesh();
00033 void test_get_ents_with_default_value();
00034 void test_bit_tag_big();
00035 void test_clear_dense();
00036 void test_clear_sparse();
00037 void test_clear_bit();
00038 void test_clear_dense_varlen();
00039 void test_clear_sparse_varlen();
00040 void test_tag_iterate_sparse();
00041 void test_tag_iterate_dense();
00042 void test_tag_iterate_sparse_default();
00043 void test_tag_iterate_dense_default();
00044 void test_tag_iterate_invalid();
00045 
00046 void regression_one_entity_by_var_tag();
00047 void regression_tag_on_nonexistent_entity();
00048 
00049 int main()
00050 {
00051     int failures = 0;
00052 
00053     failures += RUN_TEST( test_create_tag );
00054     failures += RUN_TEST( test_get_set_sparse_int );
00055     failures += RUN_TEST( test_get_set_dense_int );
00056     failures += RUN_TEST( test_get_set_dense_double );
00057     failures += RUN_TEST( test_get_set_bit );
00058     failures += RUN_TEST( test_get_by_tag );
00059     failures += RUN_TEST( test_get_by_tag_value );
00060     failures += RUN_TEST( test_get_by_tag_value_dense );
00061     failures += RUN_TEST( test_mesh_value );
00062     failures += RUN_TEST( test_get_pointers_sparse );
00063     failures += RUN_TEST( test_get_pointers_dense );
00064     failures += RUN_TEST( test_set_pointers_sparse );
00065     failures += RUN_TEST( test_set_pointers_dense );
00066     failures += RUN_TEST( test_get_entity_tags );
00067     failures += RUN_TEST( test_delete_sparse_tag );
00068     failures += RUN_TEST( test_delete_dense_tag );
00069     failures += RUN_TEST( test_delete_mesh_tag );
00070     failures += RUN_TEST( test_delete_sparse_data );
00071     failures += RUN_TEST( test_delete_dense_data );
00072     failures += RUN_TEST( test_delete_bit_data );
00073     failures += RUN_TEST( test_create_variable_length_tag );
00074     failures += RUN_TEST( test_get_set_variable_length_sparse );
00075     failures += RUN_TEST( test_get_set_variable_length_dense );
00076     failures += RUN_TEST( test_get_set_variable_length_mesh );
00077     failures += RUN_TEST( test_get_ents_with_default_value );
00078     failures += RUN_TEST( test_bit_tag_big );
00079     failures += RUN_TEST( regression_one_entity_by_var_tag );
00080     failures += RUN_TEST( regression_tag_on_nonexistent_entity );
00081     failures += RUN_TEST( test_clear_dense );
00082     failures += RUN_TEST( test_clear_sparse );
00083     failures += RUN_TEST( test_clear_bit );
00084     failures += RUN_TEST( test_clear_dense_varlen );
00085     failures += RUN_TEST( test_clear_sparse_varlen );
00086     failures += RUN_TEST( test_tag_iterate_sparse );
00087     failures += RUN_TEST( test_tag_iterate_dense );
00088     failures += RUN_TEST( test_tag_iterate_sparse_default );
00089     failures += RUN_TEST( test_tag_iterate_dense_default );
00090     failures += RUN_TEST( test_tag_iterate_invalid );
00091 
00092     if( failures ) std::cerr << "<<<< " << failures << " TESTS FAILED >>>>" << std::endl;
00093 
00094     return failures;
00095 }
00096 
00097 void setup_mesh( Interface& mesh );
00098 
00099 Tag test_create_tag( Interface& mb, const char* name, int num_vals, TagType storage, DataType type, const void* defval,
00100                      ErrorCode expect = MB_SUCCESS );
00101 
00102 Tag test_create_var_len_tag( Interface& mb, const char* name, TagType storage, DataType type, const void* defval,
00103                              int defval_size, ErrorCode expect = MB_SUCCESS );
00104 
00105 enum SetMode
00106 {
00107     NORMAL,
00108     POINTER,
00109     ONE_VALUE
00110 };
00111 
00112 void test_get_set( const char* name, int vals_per_ent, TagType storage, DataType type, const void* some_values,
00113                    int num_values, const void* default_value, SetMode set_by_pointer = NORMAL,
00114                    bool get_by_pointer = false );
00115 
00116 void test_get_set_variable_length( const char* name, TagType storage, DataType type, const void** values,
00117                                    const int* lengths, int num_values, const void* default_value,
00118                                    int default_value_length );
00119 
00120 void test_mesh_value( Interface& mb, const char* tag_name, unsigned tag_size, TagType tag_storage, DataType tag_type,
00121                       const void* value );
00122 
00123 Tag test_create_tag( Interface& mb, const char* name, int num_vals, TagType storage, DataType type, const void* defval,
00124                      ErrorCode expect )
00125 {
00126     ErrorCode rval;
00127     Tag tag;
00128 
00129     rval = mb.tag_get_handle( name, num_vals, type, tag, storage | MB_TAG_EXCL, defval );
00130     if( expect != MB_SUCCESS )
00131     {
00132         CHECK_EQUAL( expect, rval );
00133         return 0;
00134     }
00135     CHECK_ERR( rval );
00136 
00137     std::string n;
00138     rval = mb.tag_get_name( tag, n );CHECK_ERR( rval );
00139     CHECK( n == name );
00140 
00141     Tag tag2;
00142     rval = mb.tag_get_handle( name, num_vals, type, tag2 );CHECK_ERR( rval );
00143     CHECK_EQUAL( tag, tag2 );
00144 
00145     int s;
00146     rval = mb.tag_get_length( tag, s );CHECK_ERR( rval );
00147     CHECK_EQUAL( num_vals, s );
00148 
00149     TagType t;
00150     rval = mb.tag_get_type( tag, t );CHECK_ERR( rval );
00151     CHECK_EQUAL( storage, t );
00152 
00153     DataType d;
00154     rval = mb.tag_get_data_type( tag, d );CHECK_ERR( rval );
00155     CHECK_EQUAL( type, d );
00156 
00157     int bytes;
00158     rval = mb.tag_get_bytes( tag, bytes );CHECK_ERR( rval );
00159     int exp_bytes = 0;
00160     switch( type )
00161     {
00162         case MB_TYPE_INTEGER:
00163             exp_bytes = num_vals * sizeof( int );
00164             break;
00165         case MB_TYPE_DOUBLE:
00166             exp_bytes = num_vals * sizeof( double );
00167             break;
00168         case MB_TYPE_HANDLE:
00169             exp_bytes = num_vals * sizeof( EntityHandle );
00170             break;
00171         case MB_TYPE_BIT:
00172             exp_bytes = 1;
00173             break;
00174         case MB_TYPE_OPAQUE:
00175             exp_bytes = num_vals;
00176             break;
00177     }
00178     CHECK_EQUAL( exp_bytes, bytes );
00179 
00180     std::vector< unsigned char > defv( bytes );
00181     rval = mb.tag_get_default_value( tag, &defv[0] );
00182     if( defval )
00183     {
00184         CHECK_ERR( rval );
00185         CHECK( !memcmp( defval, &defv[0], bytes ) );
00186     }
00187     else
00188     {
00189         CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
00190     }
00191 
00192     // make sure we can't create a second tag w/ the same name
00193     rval = mb.tag_get_handle( name, num_vals, type, tag2, storage | MB_TAG_EXCL, defval );
00194     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00195     // we should get back the handle of the existing tag
00196     CHECK_EQUAL( tag, tag2 );
00197 
00198     return tag;
00199 }
00200 
00201 Tag test_create_var_len_tag( Interface& mb, const char* name, TagType storage, DataType type, const void* defval,
00202                              int defval_size, ErrorCode expect )
00203 {
00204     ErrorCode rval;
00205     Tag tag;
00206 
00207     rval = mb.tag_get_handle( name, defval_size, type, tag, storage | MB_TAG_VARLEN | MB_TAG_EXCL, defval );
00208     if( expect != MB_SUCCESS )
00209     {
00210         CHECK_EQUAL( expect, rval );
00211         return 0;
00212     }
00213     CHECK_ERR( rval );
00214 
00215     std::string n;
00216     rval = mb.tag_get_name( tag, n );CHECK_ERR( rval );
00217     CHECK( n == name );
00218 
00219     Tag tag2;
00220     rval = mb.tag_get_handle( name, 0, type, tag2 );CHECK_ERR( rval );
00221     CHECK_EQUAL( tag, tag2 );
00222 
00223     int s;
00224     rval = mb.tag_get_bytes( tag, s );
00225     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
00226     rval = mb.tag_get_length( tag, s );
00227     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
00228     // CHECK_ERR(rval);
00229     // CHECK_EQUAL( MB_VARIABLE_LENGTH, s );
00230 
00231     TagType t;
00232     rval = mb.tag_get_type( tag, t );CHECK_ERR( rval );
00233     CHECK_EQUAL( storage, t );
00234 
00235     DataType d;
00236     rval = mb.tag_get_data_type( tag, d );CHECK_ERR( rval );
00237     CHECK_EQUAL( type, d );
00238 
00239     int size;
00240     const void* defv;
00241     rval = mb.tag_get_default_value( tag, defv, size );
00242     if( defval )
00243     {
00244         CHECK_ERR( rval );
00245         CHECK_EQUAL( defval_size, size );
00246         CHECK( !memcmp( defval, defv, size ) );
00247     }
00248     else
00249     {
00250         CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
00251     }
00252 
00253     // make sure we can't create a second tag w/ the same name
00254     rval = mb.tag_get_handle( name, defval_size, type, tag2, storage | MB_TAG_VARLEN | MB_TAG_EXCL );
00255     CHECK_EQUAL( MB_ALREADY_ALLOCATED, rval );
00256     // we should get back the handle of the existing tag
00257     CHECK_EQUAL( tag, tag2 );
00258 
00259     return tag;
00260 }
00261 
00262 void test_create_tag()
00263 {
00264     Core mb;
00265     unsigned char defval[] = { 1, 2, 3, 4, 0, 0, 0, 0 };
00266 
00267     // opaque tags
00268     test_create_tag( mb, "opaque_tag_sparse", 8, MB_TAG_SPARSE, MB_TYPE_OPAQUE, defval );
00269     test_create_tag( mb, "opaque_tag_dense", 4, MB_TAG_DENSE, MB_TYPE_OPAQUE, defval );
00270     test_create_tag( mb, "opaque_tag_dense2", 1, MB_TAG_DENSE, MB_TYPE_OPAQUE, 0 );
00271 
00272     // integer tags
00273     test_create_tag( mb, "int_tag_sparse", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, defval );
00274     test_create_tag( mb, "int_tag_dense", 8, MB_TAG_DENSE, MB_TYPE_INTEGER, 0 );
00275 
00276     // double tags
00277     double defval2[] = { 3.14159, 2.71828 };
00278     test_create_tag( mb, "dbl_tag_sparse", 1, MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0 );
00279     test_create_tag( mb, "dbl_tag_dense", 2, MB_TAG_DENSE, MB_TYPE_DOUBLE, defval2 );
00280 
00281     // handle tags
00282     test_create_tag( mb, "h_tag_dense", 1, MB_TAG_DENSE, MB_TYPE_HANDLE, defval );
00283 
00284     // bit tags
00285     unsigned char def_bit_val = 0xBF;
00286     test_create_tag( mb, "bit_tag_1", 2, MB_TAG_BIT, MB_TYPE_BIT, &def_bit_val );
00287 }
00288 
00289 void test_create_variable_length_tag()
00290 {
00291     Core mb;
00292     unsigned char defval[] = { 1, 2, 3, 4, 0, 0, 0, 0 };
00293 
00294     // opaque tags
00295     const void* defptr = defval;
00296     test_create_var_len_tag( mb, "opaque_tag_sparse", MB_TAG_SPARSE, MB_TYPE_OPAQUE, defptr, 8 );
00297     test_create_var_len_tag( mb, "opaque_tag_dense", MB_TAG_DENSE, MB_TYPE_OPAQUE, defptr, 4 );
00298     test_create_var_len_tag( mb, "opaque_tag_dense2", MB_TAG_DENSE, MB_TYPE_OPAQUE, 0, 0 );
00299 
00300     // integer tags
00301     test_create_var_len_tag( mb, "int_tag_sparse", MB_TAG_SPARSE, MB_TYPE_INTEGER, defptr, 1 );
00302     test_create_var_len_tag( mb, "int_tag_dense", MB_TAG_DENSE, MB_TYPE_INTEGER, 0, 0 );
00303 
00304     // double tags
00305     double defval2[] = { 3.14159, 2.71828 };
00306     defptr           = defval2;
00307     test_create_var_len_tag( mb, "dbl_tag_sparse", MB_TAG_SPARSE, MB_TYPE_DOUBLE, 0, 0 );
00308     test_create_var_len_tag( mb, "dbl_tag_dense", MB_TAG_DENSE, MB_TYPE_DOUBLE, defptr, 2 );
00309 
00310     // handle tags
00311     test_create_var_len_tag( mb, "h_tag_dense", MB_TAG_DENSE, MB_TYPE_HANDLE, 0, 0 );
00312 }
00313 
00314 // Given a list of sequential values in memory (pointed to by 'concat'),
00315 // populate a list of pointers to to each value.  The number of values
00316 // is assumed to be the size of 'list'.  Individual values have a size of 'bytes'
00317 static void concat_to_list( const void* concat, std::vector< const void* >& list, size_t bytes )
00318 {
00319     const unsigned char* ptr                  = reinterpret_cast< const unsigned char* >( concat );
00320     std::vector< const void* >::iterator iter = list.begin();
00321     for( ; iter != list.end(); ++iter, ptr += bytes )
00322         *iter = ptr;
00323 }
00324 
00325 // test get/set of tag values
00326 void test_get_set( const char* name, int vals_per_ent, TagType storage, DataType type, const void* some_values,
00327                    int num_values, const void* default_value, SetMode set_mode, bool get_by_pointer )
00328 {
00329     std::vector< unsigned char > data;
00330 
00331     // create mesh and tag
00332     Core moab;
00333     Interface& mb = moab;
00334     setup_mesh( mb );
00335     Tag tag = test_create_tag( mb, name, vals_per_ent, storage, type, default_value );
00336 
00337     // get some handles to work with
00338     Range entities;
00339     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00340     CHECK( !entities.empty() );
00341 
00342     int bytes = 0;
00343     switch( type )
00344     {
00345         case MB_TYPE_INTEGER:
00346             bytes = vals_per_ent * sizeof( int );
00347             break;
00348         case MB_TYPE_DOUBLE:
00349             bytes = vals_per_ent * sizeof( double );
00350             break;
00351         case MB_TYPE_HANDLE:
00352             bytes = vals_per_ent * sizeof( EntityHandle );
00353             break;
00354         case MB_TYPE_BIT:
00355             bytes = 1;
00356             break;
00357         case MB_TYPE_OPAQUE:
00358             bytes = vals_per_ent;
00359             break;
00360     }
00361 
00362     // split handles into four groups
00363     // a) a single handle
00364     // b) some non-consecutive handles in an array
00365     // c) some handles in an Range
00366     // d) remaining handles (remaining in 'entities');
00367     EntityHandle one_handle;
00368     Range::iterator it = entities.begin() += entities.size() / 2;
00369     one_handle         = *it;
00370     entities.erase( it );
00371 
00372     Range handle_range;
00373     std::vector< EntityHandle > handle_list;
00374     for( Range::const_pair_iterator i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
00375     {
00376         if( i->first == i->second || i->second - i->first == 1 )
00377         {
00378             EntityHandle h1 = i->first, h2 = i->second;
00379             ++i;
00380             handle_range.insert( h1, h2 );
00381         }
00382         else
00383         {
00384             EntityHandle mid = ( EntityHandle )( i->first + ( i->second - i->first + 1 ) / 2 );
00385             handle_list.push_back( mid );
00386             handle_range.insert( mid + 1, i->second );
00387         }
00388     }
00389     entities = subtract( entities, handle_range );
00390     for( unsigned i = 0; i < handle_list.size(); ++i )
00391         entities.erase( handle_list[i] );
00392 
00393     // try getting/setting single handle value
00394 
00395     std::vector< const void* > list( 1 );
00396     if( set_mode == NORMAL ) { rval = mb.tag_set_data( tag, &one_handle, 1, some_values ); }
00397     else if( set_mode == POINTER )
00398     {
00399         list[0] = some_values;
00400         rval    = mb.tag_set_by_ptr( tag, &one_handle, 1, &list[0] );
00401     }
00402     else
00403     {  // set_mode == ONE_VALUE
00404         rval = mb.tag_clear_data( tag, &one_handle, 1, some_values );
00405     }
00406     CHECK_ERR( rval );
00407     data.resize( bytes );
00408     if( get_by_pointer )
00409     {
00410         // test that correct size is returned
00411         int rsize;
00412         rval = mb.tag_get_by_ptr( tag, &one_handle, 1, &list[0], &rsize );CHECK_ERR( rval );
00413         CHECK_EQUAL( vals_per_ent, rsize );
00414         // try again with NULL size pointer
00415         list[0] = 0;
00416         rval    = mb.tag_get_by_ptr( tag, &one_handle, 1, &list[0] );CHECK_ERR( rval );
00417         CHECK( !memcmp( some_values, list[0], bytes ) );
00418     }
00419     else
00420     {
00421         rval = mb.tag_get_data( tag, &one_handle, 1, &data[0] );CHECK_ERR( rval );
00422         CHECK( !memcmp( some_values, &data[0], bytes ) );
00423     }
00424 
00425     // try getting/setting for arrays of handles
00426 
00427     const int step = std::min( (int)handle_list.size(), num_values );
00428     data.resize( step * bytes );
00429     for( int i = 0; i < (int)handle_list.size(); i += step )
00430     {
00431         const int n = std::min( (int)handle_list.size() - i, step );
00432         list.resize( n );
00433         if( set_mode == NORMAL ) { rval = mb.tag_set_data( tag, &handle_list[i], n, some_values ); }
00434         else if( set_mode == POINTER )
00435         {
00436             concat_to_list( some_values, list, bytes );
00437             rval = mb.tag_set_by_ptr( tag, &handle_list[i], n, &list[0] );
00438         }
00439         else
00440         {
00441             rval = mb.tag_clear_data( tag, &handle_list[i], n, some_values );
00442         }
00443         CHECK_ERR( rval );
00444 
00445         if( get_by_pointer )
00446         {
00447             // check that valid sizes are returned if requested
00448             std::vector< int > rsizes( n, 0 );
00449             rval = mb.tag_get_by_ptr( tag, &handle_list[i], n, &list[0], &rsizes[0] );CHECK_ERR( rval );
00450             for( int j = 0; j < n; ++j )
00451                 CHECK_EQUAL( vals_per_ent, rsizes[j] );
00452             // query a second time to verify that it works w/ NULL size array
00453             list.clear();
00454             list.resize( n, 0 );
00455             rval = mb.tag_get_by_ptr( tag, &handle_list[i], n, &list[0] );
00456         }
00457         else
00458         {
00459             rval = mb.tag_get_data( tag, &handle_list[i], n, &data[0] );
00460             concat_to_list( &data[0], list, bytes );
00461         }
00462         CHECK_ERR( rval );
00463 
00464         const unsigned char* ptr = reinterpret_cast< const unsigned char* >( some_values );
00465         for( int j = 0; j < n; ++j, ptr += bytes )
00466             CHECK( !memcmp( ptr, list[j], bytes ) );
00467     }
00468 
00469     // try getting/setting for Range of handles
00470 
00471     // set data for range
00472     if( set_mode == NORMAL )
00473     {
00474         std::vector< unsigned char > input_data( handle_range.size() * bytes );
00475         for( int i = 0; i < (int)input_data.size(); i += num_values * bytes )
00476             memcpy( &input_data[i], some_values, std::min( (int)input_data.size() - i, num_values * bytes ) );
00477         rval = mb.tag_set_data( tag, handle_range, &input_data[0] );
00478     }
00479     else if( set_mode == POINTER )
00480     {
00481         list.resize( num_values );
00482         concat_to_list( some_values, list, bytes );
00483         while( list.size() < handle_range.size() )
00484         {
00485             size_t s = list.size();
00486             list.resize( 2 * s );
00487             std::copy( list.begin(), list.begin() + s, list.begin() + s );
00488         }
00489         rval = mb.tag_set_by_ptr( tag, handle_range, &list[0] );
00490     }
00491     else
00492     {
00493         rval = mb.tag_clear_data( tag, handle_range, some_values );
00494     }
00495     CHECK_ERR( rval );
00496 
00497     // get data for range
00498     list.clear();
00499     list.resize( handle_range.size(), 0 );
00500     if( get_by_pointer )
00501     {
00502         // check that valid sizes are returned if requested
00503         std::vector< int > rsizes( handle_range.size(), 0 );
00504         rval = mb.tag_get_by_ptr( tag, handle_range, &list[0], &rsizes[0] );CHECK_ERR( rval );
00505         for( size_t j = 0; j < handle_range.size(); ++j )
00506             CHECK_EQUAL( vals_per_ent, rsizes[j] );
00507         // query w/ NULL size array to make sure that works also
00508         list.clear();
00509         list.resize( handle_range.size(), 0 );
00510         rval = mb.tag_get_by_ptr( tag, handle_range, &list[0] );
00511     }
00512     else
00513     {
00514         data.resize( handle_range.size() * bytes );
00515         concat_to_list( &data[0], list, bytes );
00516         rval = mb.tag_get_data( tag, handle_range, &data[0] );
00517     }
00518     CHECK_ERR( rval );
00519 
00520     // compare values
00521     const bool dstep = ( set_mode != ONE_VALUE );
00522     for( size_t i = 0; i < list.size(); ++i )
00523     {
00524         CHECK( list[i * dstep] != NULL );
00525         const void* ptr = reinterpret_cast< const char* >( some_values ) + ( i % num_values ) * bytes;
00526         CHECK( !memcmp( list[i * dstep], ptr, bytes ) );
00527     }
00528 
00529     // try getting unset values
00530 
00531     list.resize( entities.size() );
00532     if( get_by_pointer ) { rval = mb.tag_get_by_ptr( tag, entities, &list[0] ); }
00533     else
00534     {
00535         data.clear(), data.resize( entities.size() * bytes, '\001' );
00536         concat_to_list( &data[0], list, bytes );
00537         rval = mb.tag_get_data( tag, entities, &data[0] );
00538     }
00539     // if there was a default value, we should have gotten it for all unset entities
00540     if( default_value )
00541     {
00542         CHECK_ERR( rval );
00543         for( unsigned i = 0; i < entities.size(); ++i )
00544             CHECK( !memcmp( default_value, list[i], bytes ) );
00545     }
00546     // otherwise we should get MB_TAG_NOT_FOUND, *unless* the tag
00547     // is dense, in which case we /might/ get all zero bytes instead.
00548     else if( MB_TAG_NOT_FOUND != rval )
00549     {
00550         CHECK_EQUAL( MB_TAG_DENSE, storage );
00551         std::vector< unsigned char > zeros( bytes, 0 );
00552         for( unsigned i = 0; i < entities.size(); ++i )
00553             CHECK( !memcmp( &zeros[0], list[i], bytes ) );
00554     }
00555 
00556     // Check that handles for other entities didn't change.
00557 
00558     // Ignore get_by_pointer/set_by_pointer flags from here on.
00559     // We've established (hopefully) that both methods work in
00560     // the above code.  Now we just want to verify correct values,
00561     // regardless of the API used to get them.
00562 
00563     // one handle
00564     data.resize( bytes );
00565     rval = mb.tag_get_data( tag, &one_handle, 1, &data[0] );CHECK_ERR( rval );
00566     CHECK( !memcmp( some_values, &data[0], bytes ) );
00567 
00568     // array values
00569     data.resize( step * bytes );
00570     for( int i = 0; i < (int)handle_list.size(); i += step )
00571     {
00572         const int n = std::min( (int)handle_list.size() - i, step );
00573         rval        = mb.tag_get_data( tag, &handle_list[i], n, &data[0] );CHECK_ERR( rval );
00574         CHECK( !memcmp( some_values, &data[0], step * bytes ) );
00575         rval = mb.tag_set_data( tag, &handle_list[i], n, some_values );CHECK_ERR( rval );
00576     }
00577 
00578     // range values
00579     list.clear();
00580     list.resize( handle_range.size(), 0 );
00581     rval = mb.tag_get_by_ptr( tag, handle_range, &list[0] );CHECK_ERR( rval );
00582     for( size_t i = 0; i < handle_range.size(); ++i )
00583     {
00584         const void* ptr = reinterpret_cast< const char* >( some_values ) + ( i % num_values ) * bytes;
00585         CHECK( !memcmp( ptr, list[i], bytes ) );
00586     }
00587 }
00588 
00589 void test_get_set_sparse_int()
00590 {
00591     const int data[]  = { 21, 00, 46, 30, 26, 63, 05, 49, 31, 39, 86, 77, 24, 37, 25, 98,
00592                          26, 20, 01, 54, 16, 28, 55, 49, 96, 18, 28, 18, 53, 00, 80, 48 };
00593     const int num_val = sizeof( data ) / sizeof( data[0] );
00594 
00595     test_get_set( "sparse_int", 2, MB_TAG_SPARSE, MB_TYPE_INTEGER, data, num_val / 2, 0 );
00596 
00597     const int defaultval = 19740508;
00598     test_get_set( "sparse_int_def", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, data, num_val, &defaultval );
00599 }
00600 
00601 void test_get_set_dense_int()
00602 {
00603     const int data[]  = { 231, 416, 294, 504, 318, 558, 494, 006, 464, 648, 737, 045, 179, 852, 944, 336,
00604                          773, 248, 434, 615, 677, 667, 521, 748, 820, 533, 955, 300, 108, 726, 747, 597 };
00605     const int num_val = sizeof( data ) / sizeof( data[0] );
00606 
00607     test_get_set( "dense_int", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, data, num_val, 0 );
00608 
00609     const int defaultval[] = { 5, 8, 1974 };
00610     test_get_set( "dense_int_def", 3, MB_TAG_DENSE, MB_TYPE_INTEGER, data, num_val / 3, defaultval );
00611 }
00612 
00613 void test_get_set_dense_double()
00614 {
00615     const double pi     = 3.1415926535897931;
00616     const double e      = 2.7182818284590451;
00617     const double data[] = { 1,      1.,     pi,     e,      2,      1. / 2, 2 * pi, e / 2,  3,      1. / 3,
00618                             3 * pi, e / 3,  4,      1. / 4, 4 * pi, e / 4,  5,      1. / 5, 5 * pi, e / 5,
00619                             6,      1. / 6, 6 * pi, e / 6,  0,      100,    1000,   10000 };
00620     const int num_val   = sizeof( data ) / sizeof( data[0] );
00621 
00622     test_get_set( "dense_dbl", 1, MB_TAG_DENSE, MB_TYPE_DOUBLE, data, num_val, 0 );
00623 
00624     const double defaultval[] = { 0.11, 0.22 };
00625     test_get_set( "dense_dbl_def", 2, MB_TAG_DENSE, MB_TYPE_DOUBLE, data, num_val / 2, defaultval );
00626 }
00627 
00628 void test_get_pointers_sparse()
00629 {
00630     const double data[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16 };
00631     const int num_val   = sizeof( data ) / sizeof( data[0] );
00632 
00633     test_get_set( "sparse_dbl_ptr", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, 0, NORMAL, true );
00634 
00635     const double defaultval[] = { -1, -2 };
00636     test_get_set( "sparse_dbl_ptr_def", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, defaultval, NORMAL, true );
00637 }
00638 
00639 void test_get_pointers_dense()
00640 {
00641     const unsigned char data[] = "a few aribtrary bytes entered as a string";
00642     const int num_val          = sizeof( data ) / sizeof( data[0] );
00643 
00644     test_get_set( "dense_byte_ptr", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, 0, NORMAL, true );
00645 
00646     const unsigned char defaultval[] = "XY";
00647     test_get_set( "dense_byte_ptr_def", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, defaultval, NORMAL, true );
00648 }
00649 
00650 void test_set_pointers_sparse()
00651 {
00652     const double data[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16 };
00653     const int num_val   = sizeof( data ) / sizeof( data[0] );
00654 
00655     test_get_set( "sparse_dbl_ptr", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, 0, POINTER, false );
00656 
00657     const double defaultval[] = { -1, -2 };
00658     test_get_set( "sparse_dbl_ptr_def", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, data, num_val / 2, defaultval, POINTER,
00659                   false );
00660 }
00661 
00662 void test_set_pointers_dense()
00663 {
00664     const unsigned char data[] = "a few aribtrary bytes entered as a string";
00665     const int num_val          = sizeof( data ) / sizeof( data[0] );
00666 
00667     test_get_set( "dense_byte_ptr", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, 0, POINTER, false );
00668 
00669     const unsigned char defaultval[] = "XY";
00670     test_get_set( "dense_byte_ptr_def", 2, MB_TAG_DENSE, MB_TYPE_OPAQUE, data, num_val / 2, defaultval, POINTER,
00671                   false );
00672 
00673     const double dbldata[3] = { 1.0, 2.0, 3.0 };
00674     const int dbl_num_val   = sizeof( dbldata ) / sizeof( double );
00675 
00676     test_get_set( "dense_double_ptr", 3, MB_TAG_DENSE, MB_TYPE_DOUBLE, dbldata, dbl_num_val, 0, POINTER, false );
00677 
00678     const double dbldefaultval[3] = { 0.0, 0.0, 0.0 };
00679     test_get_set( "dense_byte_ptr_def", 3, MB_TAG_DENSE, MB_TYPE_DOUBLE, dbldata, dbl_num_val, dbldefaultval, POINTER,
00680                   false );
00681 }
00682 
00683 void test_clear_dense()
00684 {
00685     const int int_val = 0xcab;
00686     test_get_set( "clear_dense_int", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, &int_val, 1, 0, ONE_VALUE, false );
00687 
00688     const double dbl_val[]     = { 3.14159, -3.14159 };
00689     const double default_val[] = { -2, 5 };
00690     test_get_set( "clear_dense_double", 2, MB_TAG_DENSE, MB_TYPE_DOUBLE, &dbl_val, 1, default_val, ONE_VALUE, false );
00691 }
00692 
00693 void test_clear_sparse()
00694 {
00695     const int int_val = 0xcab;
00696     test_get_set( "clear_sparse_int", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &int_val, 1, 0, ONE_VALUE, false );
00697 
00698     const double dbl_val[]     = { 3.14159, -3.14159 };
00699     const double default_val[] = { -2, 5 };
00700     test_get_set( "clear_sparse_double", 2, MB_TAG_SPARSE, MB_TYPE_DOUBLE, &dbl_val, 1, default_val, ONE_VALUE, false );
00701 }
00702 
00703 void test_get_set_bit()
00704 {
00705     // create mesh and tag
00706     Core moab;
00707     Interface& mb = moab;
00708     setup_mesh( mb );
00709     Tag tag = test_create_tag( mb, "bit_val", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
00710 
00711     // get some handles to work with
00712     Range entities;
00713     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00714     CHECK( !entities.empty() );
00715 
00716     // set bits on every entity
00717     unsigned counter = 0;
00718     for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
00719     {
00720         srand( counter++ );
00721         unsigned char bits = (unsigned char)( rand() & 3 );
00722         rval               = mb.tag_set_data( tag, &*i, 1, &bits );CHECK_ERR( rval );
00723         unsigned char bits_out = 0;
00724         rval                   = mb.tag_get_data( tag, &*i, 1, &bits_out );CHECK_ERR( rval );
00725         CHECK_EQUAL( bits, bits_out );
00726     }
00727 
00728     // test default value
00729     unsigned char defval = '\003';
00730     unsigned char zero   = '\0';
00731     Tag tag2             = test_create_tag( mb, "bit_val2", 3, MB_TAG_BIT, MB_TYPE_BIT, &defval );
00732     CHECK( entities.size() >= 3 );
00733     Range::iterator j = entities.begin();
00734     EntityHandle h1   = *j;
00735     ++j;
00736     EntityHandle h2 = *j;
00737     ++j;
00738     EntityHandle h3 = *j;
00739     ++j;
00740     rval = mb.tag_set_data( tag2, &h1, 1, &zero );CHECK_ERR( rval );
00741     rval = mb.tag_set_data( tag2, &h3, 1, &zero );CHECK_ERR( rval );
00742     unsigned char byte;
00743     rval = mb.tag_get_data( tag2, &h2, 1, &byte );CHECK_ERR( rval );
00744     CHECK_EQUAL( defval, byte );
00745     rval = mb.tag_get_data( tag2, &h1, 1, &byte );CHECK_ERR( rval );
00746     CHECK_EQUAL( zero, byte );
00747     rval = mb.tag_get_data( tag2, &h3, 1, &byte );CHECK_ERR( rval );
00748     CHECK_EQUAL( zero, byte );
00749 
00750     // test default value for uninitialized data (tag not set for any entity)
00751     defval   = '\002';
00752     Tag tag3 = test_create_tag( mb, "bit_val3", 2, MB_TAG_BIT, MB_TYPE_BIT, &defval );
00753     rval     = mb.tag_get_data( tag3, &h2, 1, &byte );CHECK_ERR( rval );
00754     CHECK_EQUAL( defval, byte );
00755 }
00756 
00757 void test_clear_bit()
00758 {
00759     // create mesh and tag
00760     Core moab;
00761     Interface& mb = moab;
00762     setup_mesh( mb );
00763     Tag tag = test_create_tag( mb, "clear_bit_val", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
00764 
00765     // get some handles to work with
00766     Range entities;
00767     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
00768     CHECK( !entities.empty() );
00769 
00770     const unsigned char bits = 2;
00771     rval                     = mb.tag_clear_data( tag, entities, &bits );CHECK_ERR( rval );
00772 
00773     // set bits on every entity
00774     for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
00775     {
00776         unsigned char bits_out = 0;
00777         rval                   = mb.tag_get_data( tag, &*i, 1, &bits_out );
00778         CHECK_EQUAL( bits, bits_out );
00779     }
00780 }
00781 
00782 void test_get_by_tag()
00783 {
00784     // create mesh and tag
00785     Core moab;
00786     Interface& mb = moab;
00787     setup_mesh( mb );
00788     Tag tag = test_create_tag( mb, "sparse_count", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
00789 
00790     // get some handles to work with
00791     Range entities;
00792     ErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, entities );CHECK_ERR( rval );
00793     CHECK( !entities.empty() );
00794 
00795     // get five handles
00796     CHECK( entities.size() > 6 );
00797     EntityHandle arr[5] = { *( entities.begin() += entities.size() / 6 ),
00798                             *( entities.begin() += 2 * entities.size() / 6 ),
00799                             *( entities.begin() += 3 * entities.size() / 6 ),
00800                             *( entities.begin() += 4 * entities.size() / 6 ),
00801                             *( entities.begin() += 5 * entities.size() / 6 ) };
00802     int values[5]       = { 1, 2, 3, 4, 5 };
00803     rval                = mb.tag_set_data( tag, arr, 5, values );CHECK_ERR( rval );
00804     const void* const valarr[1] = { 0 };
00805 
00806     // put some in a mesh set
00807     EntityHandle set;
00808     const int num_in_set = 3;
00809     rval                 = mb.create_meshset( 0, set );CHECK_ERR( rval );
00810     rval = mb.add_entities( set, arr, num_in_set );CHECK_ERR( rval );
00811 
00812     // try for whole mesh will null tag value array
00813     int count = -1;
00814     rval      = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, count );CHECK_ERR( rval );
00815     CHECK_EQUAL( 5, count );
00816 
00817     // try for whole mesh will null tag value, but non-null array
00818     count = -1;
00819     rval  = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, count );CHECK_ERR( rval );
00820     CHECK_EQUAL( 5, count );
00821 
00822     // try for mesh set
00823     rval = mb.get_number_entities_by_type_and_tag( set, MBVERTEX, &tag, 0, 1, count );CHECK_ERR( rval );
00824     CHECK_EQUAL( num_in_set, count );
00825 
00826     // try for whole mesh will null tag value array
00827     Range found;
00828     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, found );CHECK_ERR( rval );
00829     CHECK_EQUAL( 5u, (unsigned)found.size() );
00830     Range::iterator i = found.begin();
00831     CHECK_EQUAL( arr[0], *i );
00832     ++i;
00833     CHECK_EQUAL( arr[1], *i );
00834     ++i;
00835     CHECK_EQUAL( arr[2], *i );
00836     ++i;
00837     CHECK_EQUAL( arr[3], *i );
00838     ++i;
00839     CHECK_EQUAL( arr[4], *i );
00840 
00841     // try for whole mesh will null tag value, but non-null array
00842     found.clear();
00843     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, found );CHECK_ERR( rval );
00844     CHECK_EQUAL( 5u, (unsigned)found.size() );
00845     i = found.begin();
00846     CHECK_EQUAL( arr[0], *i );
00847     ++i;
00848     CHECK_EQUAL( arr[1], *i );
00849     ++i;
00850     CHECK_EQUAL( arr[2], *i );
00851     ++i;
00852     CHECK_EQUAL( arr[3], *i );
00853     ++i;
00854     CHECK_EQUAL( arr[4], *i );
00855 
00856     // try for mesh set
00857     found.clear();
00858     rval = mb.get_entities_by_type_and_tag( set, MBVERTEX, &tag, 0, 1, found );CHECK_ERR( rval );
00859     CHECK_EQUAL( 3u, (unsigned)found.size() );
00860     i = found.begin();
00861     CHECK_EQUAL( arr[0], *i );
00862     ++i;
00863     CHECK_EQUAL( arr[1], *i );
00864     ++i;
00865     CHECK_EQUAL( arr[2], *i );
00866 }
00867 
00868 void test_get_by_tag_value()
00869 {
00870     // create mesh and tag
00871     Core moab;
00872     Interface& mb = moab;
00873     setup_mesh( mb );
00874     Tag tag = test_create_tag( mb, "sparse_count", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
00875 
00876     // get some handles to work with
00877     Range entities;
00878     ErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, entities );CHECK_ERR( rval );
00879     CHECK( !entities.empty() );
00880 
00881     // get five handles
00882     CHECK( entities.size() > 6 );
00883     EntityHandle arr[5] = { *( entities.begin() += entities.size() / 6 ),
00884                             *( entities.begin() += 2 * entities.size() / 6 ),
00885                             *( entities.begin() += 3 * entities.size() / 6 ),
00886                             *( entities.begin() += 4 * entities.size() / 6 ),
00887                             *( entities.begin() += 5 * entities.size() / 6 ) };
00888     int values[5]       = { 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF, 0xBEEF };
00889     rval                = mb.tag_set_data( tag, arr, 5, values );CHECK_ERR( rval );
00890     const void* const valarr[1] = { values };
00891 
00892     // put some in a mesh set
00893     EntityHandle set;
00894     const int num_in_set = 3;
00895     rval                 = mb.create_meshset( 0, set );CHECK_ERR( rval );
00896     rval = mb.add_entities( set, arr, num_in_set );CHECK_ERR( rval );
00897 
00898     // try for whole mesh
00899     int count = -1;
00900     rval      = mb.get_number_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, count );CHECK_ERR( rval );
00901     CHECK_EQUAL( 5, count );
00902 
00903     // try for mesh set
00904     rval = mb.get_number_entities_by_type_and_tag( set, MBVERTEX, &tag, valarr, 1, count );CHECK_ERR( rval );
00905     CHECK_EQUAL( num_in_set, count );
00906 
00907     // try for whole mesh
00908     Range found;
00909     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, valarr, 1, found );CHECK_ERR( rval );
00910     CHECK_EQUAL( 5u, (unsigned)found.size() );
00911     Range::iterator i = found.begin();
00912     CHECK_EQUAL( arr[0], *i );
00913     ++i;
00914     CHECK_EQUAL( arr[1], *i );
00915     ++i;
00916     CHECK_EQUAL( arr[2], *i );
00917     ++i;
00918     CHECK_EQUAL( arr[3], *i );
00919     ++i;
00920     CHECK_EQUAL( arr[4], *i );  //++i;
00921 
00922     // try for mesh set
00923     found.clear();
00924     rval = mb.get_entities_by_type_and_tag( set, MBVERTEX, &tag, valarr, 1, found );CHECK_ERR( rval );
00925     CHECK_EQUAL( 3u, (unsigned)found.size() );
00926     i = found.begin();
00927     CHECK_EQUAL( arr[0], *i );
00928     ++i;
00929     CHECK_EQUAL( arr[1], *i );
00930     ++i;
00931     CHECK_EQUAL( arr[2], *i );  //++i;
00932 }
00933 
00934 void test_get_by_tag_value_dense()
00935 {
00936     // create mesh and tag
00937     ErrorCode rval;
00938     Core moab;
00939     Interface& mb = moab;
00940     setup_mesh( mb );
00941     const int def_val  = 0xABCD;
00942     const int fill_val = 0xBEEF;
00943     const int find_val = 0xFEED;
00944     Tag tag            = test_create_tag( mb, "dense_gbv", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, &def_val );
00945 
00946     // get some handles to work with
00947     Range elements, vertices, results;
00948     rval = mb.get_entities_by_type( 0, MBHEX, elements );CHECK_ERR( rval );
00949     rval = mb.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval );
00950     CHECK( !elements.empty() );
00951 
00952     // set tag on all vertices to fill_val
00953     rval = mb.tag_clear_data( tag, vertices, &fill_val );CHECK_ERR( rval );
00954 
00955     // select three handles
00956     CHECK( elements.size() > 4 );
00957     EntityHandle arr[3] = { *( elements.begin() += elements.size() / 4 ),
00958                             *( elements.begin() += 2 * elements.size() / 4 ),
00959                             *( elements.begin() += 3 * elements.size() / 4 ) };
00960     int values[3]       = { find_val, find_val, find_val };
00961     rval                = mb.tag_set_data( tag, arr, 3, values );CHECK_ERR( rval );
00962 
00963     // get the entities tagged with 'find_val'
00964     const void* const findarr[1] = { &find_val };
00965     results.clear();
00966     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &tag, findarr, 1, results );CHECK_ERR( rval );
00967     CHECK_EQUAL( (size_t)3, results.size() );
00968     CHECK_EQUAL( arr[0], results.front() );
00969     CHECK_EQUAL( arr[1], *++results.begin() );
00970     CHECK_EQUAL( arr[2], results.back() );
00971 
00972     // should get no vertices
00973     results.clear();
00974     rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, findarr, 1, results );CHECK_ERR( rval );
00975     CHECK( results.empty() );
00976 
00977     // try intersecting with an existing range
00978     results = elements;
00979     results.erase( arr[1] );
00980     results.insert( vertices.front() );
00981     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &tag, findarr, 1, results, Interface::INTERSECT );CHECK_ERR( rval );
00982     CHECK_EQUAL( (size_t)2, results.size() );
00983     CHECK_EQUAL( arr[0], results.front() );
00984     CHECK_EQUAL( arr[2], results.back() );
00985 
00986     // try getting entities with default value
00987     const void* const defarr[1] = { &def_val };
00988     results.clear();
00989     rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &tag, defarr, 1, results );CHECK_ERR( rval );
00990     CHECK_EQUAL( elements.size() - 3, results.size() );
00991     Range expected( elements );
00992     expected.erase( arr[0] );
00993     expected.erase( arr[1] );
00994     expected.erase( arr[2] );
00995     CHECK( expected == results );
00996 }
00997 
00998 void test_mesh_value( Interface& mb, const char* tag_name, unsigned tag_size, TagType tag_storage, DataType tag_type,
00999                       const void* value )
01000 {
01001     // create  tag
01002     Tag tag = test_create_tag( mb, tag_name, tag_size, tag_storage, tag_type, 0 );
01003 
01004     unsigned memcmp_size = tag_size;
01005     if( tag_storage == MB_TAG_BIT || tag_type == MB_TYPE_BIT )
01006         memcmp_size = 1;
01007     else if( tag_type == MB_TYPE_DOUBLE )
01008         memcmp_size = sizeof( double );
01009     else if( tag_type == MB_TYPE_INTEGER )
01010         memcmp_size = sizeof( int );
01011     if( tag_type == MB_TYPE_HANDLE ) memcmp_size = sizeof( EntityHandle );
01012 
01013     const EntityHandle mesh = 0;
01014     ErrorCode rval          = mb.tag_set_data( tag, &mesh, 1, value );CHECK_ERR( rval );
01015     std::vector< unsigned char > bytes( memcmp_size, 0 );
01016     rval = mb.tag_get_data( tag, &mesh, 1, &bytes[0] );CHECK_ERR( rval );
01017     CHECK( !memcmp( value, &bytes[0], memcmp_size ) );
01018 
01019     // test again, this time for default value
01020     std::string name2( tag_name );
01021     name2 += "_DEF";
01022     Tag tag2 = test_create_tag( mb, name2.c_str(), tag_size, tag_storage, tag_type, value );
01023     bytes.clear();
01024     bytes.resize( memcmp_size, 0 );
01025     rval = mb.tag_get_data( tag2, &mesh, 1, &bytes[0] );CHECK_ERR( rval );
01026     CHECK( !memcmp( value, &bytes[0], memcmp_size ) );
01027 }
01028 
01029 void test_mesh_value()
01030 {
01031     Core moab;
01032 
01033     double dval = -0.5;
01034     test_mesh_value( moab, "mvd", 1, MB_TAG_DENSE, MB_TYPE_DOUBLE, &dval );
01035 
01036     int sval = 42;
01037     test_mesh_value( moab, "mvs", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &sval );
01038 
01039     EntityHandle mval = 0;
01040     test_mesh_value( moab, "mvm", 1, MB_TAG_MESH, MB_TYPE_HANDLE, &mval );
01041 
01042     unsigned char bits = '\002';
01043     test_mesh_value( moab, "mvb", 2, MB_TAG_BIT, MB_TYPE_BIT, &bits );
01044 }
01045 
01046 static void test_delete_type_tag( TagType storage )
01047 {
01048     Core moab;
01049     Interface& mb = moab;
01050     ErrorCode rval;
01051 
01052     setup_mesh( mb );
01053 
01054     // create tag
01055     int default_val     = 42;
01056     const char* tagname = "dead_tag";
01057     Tag tag             = test_create_tag( mb, tagname, 1, storage, MB_TYPE_INTEGER, &default_val );
01058 
01059     // get an entity handle to work with
01060     Range verts;
01061     rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
01062     CHECK( !verts.empty() );
01063     EntityHandle handle = verts.front();
01064 
01065     // set tag value on entity
01066     int value = -5;
01067     if( storage != MB_TAG_MESH )
01068     {
01069         rval = mb.tag_set_data( tag, &handle, 1, &value );CHECK_ERR( rval );
01070     }
01071 
01072     // set tag value on mesh
01073     const EntityHandle mesh = 0;
01074     value                   = 2;
01075     rval                    = mb.tag_set_data( tag, &mesh, 1, &value );CHECK_ERR( rval );
01076 
01077     // delete tag
01078     rval = mb.tag_delete( tag );CHECK_ERR( rval );
01079 
01080     // make sure all basic queries fail with MB_TAG_NOT_FOUND
01081     std::string name;
01082     rval = mb.tag_get_name( tag, name );
01083     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01084     Tag tag2;
01085     rval = mb.tag_get_handle( tagname, 1, MB_TYPE_INTEGER, tag2 );
01086     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01087     int size;
01088     rval = mb.tag_get_bytes( tag, size );
01089     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01090     rval = mb.tag_get_length( tag, size );
01091     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01092     // get get the type from the handle, so this still succeeds
01093     // TagType storage2;
01094     // rval = mb.tag_get_type( tag, storage2 );
01095     // CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01096     DataType type;
01097     rval = mb.tag_get_data_type( tag, type );
01098     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01099     rval = mb.tag_get_default_value( tag, &value );
01100     CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01101 
01102     // check global list of tags
01103     std::vector< Tag > tags;
01104     rval = mb.tag_get_tags( tags );CHECK_ERR( rval );
01105     CHECK( std::find( tags.begin(), tags.end(), tag ) == tags.end() );
01106 
01107     // check tags on entity
01108     tags.clear();
01109     rval = mb.tag_get_tags_on_entity( handle, tags );CHECK_ERR( rval );
01110     CHECK( std::find( tags.begin(), tags.end(), tag ) == tags.end() );
01111 
01112     // check that a new tag w/ the same name can be created
01113     tag  = test_create_tag( mb, tagname, 1, storage, MB_TYPE_DOUBLE, 0 );
01114     rval = mb.tag_delete( tag );CHECK_ERR( rval );
01115 }
01116 
01117 template < typename Container >
01118 ErrorCode set_bit_data( Interface& mb, Tag tag, const Container& handles, const std::vector< unsigned char >& data )
01119 {
01120     ErrorCode rval;
01121     data.resize( handles.size() );
01122     std::vector< unsigned char >::const_iterator j = data.begin();
01123     for( typename Container::const_iterator i = handles.begin(); i != handles.end(); ++i, ++j )
01124     {
01125         rval = mb.tag_set_data( tag, &*i, 1, &*j );
01126         if( MB_SUCCESS != rval ) return rval;
01127     }
01128 }
01129 
01130 static bool contains_tag( Tag tag, const std::vector< Tag >& list )
01131 {
01132     return std::find( list.begin(), list.end(), tag ) != list.end();
01133 }
01134 
01135 void test_get_entity_tags()
01136 {
01137     Core moab;
01138     Interface& mb = moab;
01139     ErrorCode rval;
01140 
01141     // get 8 handles to work with
01142     setup_mesh( mb );
01143     Range entities;
01144     rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
01145     CHECK( entities.size() >= 8 );
01146     Range::iterator i       = entities.begin();
01147     EntityHandle sparse_ent = *i;
01148     ++i;
01149     EntityHandle dense_ent = *i;
01150     ++i;
01151     EntityHandle bit_ent = *i;
01152     ++i;
01153     EntityHandle sparse_dense_ent = *i;
01154     ++i;
01155     EntityHandle sparse_bit_ent = *i;
01156     ++i;
01157     EntityHandle dense_bit_ent = *i;
01158     ++i;
01159     EntityHandle all_tag_ent = *i;
01160     ++i;
01161     EntityHandle no_tag_ent = *i;
01162     ++i;
01163 
01164     // create three tags to work with
01165     Tag sparse, dense, bit;
01166     sparse = test_create_tag( mb, "sparse", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, 0 );
01167     dense  = test_create_tag( mb, "dense_", 1, MB_TAG_DENSE, MB_TYPE_INTEGER, 0 );
01168     bit    = test_create_tag( mb, "bit___", 1, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01169 
01170     // set tags on handles
01171     EntityHandle sparse_ents[4] = { sparse_ent, sparse_dense_ent, sparse_bit_ent, all_tag_ent };
01172     EntityHandle dense_ents[4]  = { dense_ent, sparse_dense_ent, dense_bit_ent, all_tag_ent };
01173     EntityHandle bit_ents[4]    = { bit_ent, sparse_bit_ent, dense_bit_ent, all_tag_ent };
01174     int values[4]               = { -1, -2, -3, -4 };
01175     rval                        = mb.tag_set_data( sparse, sparse_ents, 4, &values );CHECK_ERR( rval );
01176     rval = mb.tag_set_data( dense, dense_ents, 4, &values );CHECK_ERR( rval );
01177     for( int j = 0; j < 4; ++j )
01178     {
01179         unsigned char bitval = 0xF;
01180         rval                 = mb.tag_set_data( bit, bit_ents + j, 1, &bitval );CHECK_ERR( rval );
01181     }
01182 
01183     // get tags on each entity
01184     std::vector< Tag > sparse_ent_tags, dense_ent_tags, bit_ent_tags, sparse_dense_ent_tags, sparse_bit_ent_tags,
01185         dense_bit_ent_tags, all_tag_ent_tags, no_tag_ent_tags;
01186     rval = mb.tag_get_tags_on_entity( sparse_ent, sparse_ent_tags );CHECK_ERR( rval );
01187     rval = mb.tag_get_tags_on_entity( dense_ent, dense_ent_tags );CHECK_ERR( rval );
01188     rval = mb.tag_get_tags_on_entity( bit_ent, bit_ent_tags );CHECK_ERR( rval );
01189     rval = mb.tag_get_tags_on_entity( sparse_dense_ent, sparse_dense_ent_tags );CHECK_ERR( rval );
01190     rval = mb.tag_get_tags_on_entity( sparse_bit_ent, sparse_bit_ent_tags );CHECK_ERR( rval );
01191     rval = mb.tag_get_tags_on_entity( dense_bit_ent, dense_bit_ent_tags );CHECK_ERR( rval );
01192     rval = mb.tag_get_tags_on_entity( all_tag_ent, all_tag_ent_tags );CHECK_ERR( rval );
01193     rval = mb.tag_get_tags_on_entity( no_tag_ent, no_tag_ent_tags );CHECK_ERR( rval );
01194 
01195     // check expected values
01196     // NOTE:  could potentially get back bit and dense tags for any entity
01197     //        depending on the storage layout.  Only sparse tags guarantee
01198     //        no false positives.  False negatives should never happen for any type.
01199     //        Also, there could be other dense tags already defined.
01200 
01201     // verify sparse tag in all expected lists
01202     CHECK( contains_tag( sparse, sparse_ent_tags ) );
01203     CHECK( contains_tag( sparse, sparse_dense_ent_tags ) );
01204     CHECK( contains_tag( sparse, sparse_bit_ent_tags ) );
01205     CHECK( contains_tag( sparse, all_tag_ent_tags ) );
01206 
01207     // verify sparse tag not in any other lists
01208     CHECK( !contains_tag( sparse, dense_ent_tags ) );
01209     CHECK( !contains_tag( sparse, bit_ent_tags ) );
01210     CHECK( !contains_tag( sparse, dense_bit_ent_tags ) );
01211     CHECK( !contains_tag( sparse, no_tag_ent_tags ) );
01212 
01213     // verify dense tag in all expected lists
01214     CHECK( contains_tag( dense, dense_ent_tags ) );
01215     CHECK( contains_tag( dense, sparse_dense_ent_tags ) );
01216     CHECK( contains_tag( dense, dense_bit_ent_tags ) );
01217     CHECK( contains_tag( dense, all_tag_ent_tags ) );
01218 
01219     // verify bit tag in all expected lists
01220     CHECK( contains_tag( bit, bit_ent_tags ) );
01221     CHECK( contains_tag( bit, sparse_bit_ent_tags ) );
01222     CHECK( contains_tag( bit, dense_bit_ent_tags ) );
01223     CHECK( contains_tag( bit, all_tag_ent_tags ) );
01224 }
01225 
01226 void test_delete_sparse_tag()
01227 {
01228     test_delete_type_tag( MB_TAG_SPARSE );
01229 }
01230 
01231 void test_delete_dense_tag()
01232 {
01233     test_delete_type_tag( MB_TAG_DENSE );
01234 }
01235 
01236 void test_delete_mesh_tag()
01237 {
01238     test_delete_type_tag( MB_TAG_MESH );
01239 }
01240 
01241 void test_delete_tag_data( TagType storage, bool with_default_value )
01242 {
01243     Core moab;
01244     Interface& mb = moab;
01245     ErrorCode rval;
01246 
01247     setup_mesh( mb );
01248 
01249     // subdivide entity handles into three groups:
01250     // 1) entities for which the tag data will be deleted using the array-based function
01251     // 2) entities for which the tag data will be deleted using the range-based function
01252     // 3) entities for which the tag data will not be deleted
01253     Range all_entities, del1_range, keep_range;
01254     std::vector< EntityHandle > del1_list, del2_list, keep_list;
01255     rval = mb.get_entities_by_handle( 0, all_entities );CHECK_ERR( rval );
01256     int c = 0;
01257     for( Range::iterator i = all_entities.begin(); i != all_entities.end(); ++i, ++c )
01258     {
01259         switch( c % 3 )
01260         {
01261             case 0:
01262                 del1_range.insert( *i );
01263                 break;
01264             case 1:
01265                 keep_range.insert( *i );
01266                 break;
01267             case 2:
01268                 del2_list.push_back( *i );
01269                 break;
01270         }
01271     }
01272     del1_list.resize( del1_range.size() );
01273     std::copy( del1_range.begin(), del1_range.end(), del1_list.begin() );
01274     keep_list.resize( keep_range.size() );
01275     std::copy( keep_range.begin(), keep_range.end(), keep_list.begin() );
01276 
01277     // create tag
01278     EntityHandle first   = all_entities.front();
01279     EntityHandle* defval = with_default_value ? &first : 0;
01280     const char* tagname  = "dead_tag";
01281     Tag tag              = test_create_tag( mb, tagname, 1, storage, MB_TYPE_HANDLE, defval );
01282 
01283     // set value for each entity to its handle
01284     rval = mb.tag_set_data( tag, del1_range, &del1_list[0] );CHECK_ERR( rval );
01285     rval = mb.tag_set_data( tag, keep_range, &keep_list[0] );CHECK_ERR( rval );
01286     rval = mb.tag_set_data( tag, &del2_list[0], del2_list.size(), &del2_list[0] );CHECK_ERR( rval );
01287 
01288     // delete tag data
01289     rval = mb.tag_delete_data( tag, del1_range );CHECK_ERR( rval );
01290     rval = mb.tag_delete_data( tag, &del2_list[0], del2_list.size() );CHECK_ERR( rval );
01291 
01292     // test that keep list is unaffected
01293     std::vector< EntityHandle > tag_data( keep_range.size(), 0 );
01294     rval = mb.tag_get_data( tag, keep_range, &tag_data[0] );CHECK_ERR( rval );
01295     CHECK( tag_data == keep_list );
01296 
01297     // try to get data for deleted range
01298     tag_data.clear();
01299     tag_data.resize( del1_range.size(), (EntityHandle)-1 );
01300     rval = mb.tag_get_data( tag, del1_range, &tag_data[0] );
01301     // if we have a default value, should get that for deleted entities
01302     if( with_default_value )
01303     {
01304         CHECK_ERR( rval );
01305         std::vector< EntityHandle > expected( del1_range.size(), *defval );
01306         CHECK( expected == tag_data );
01307     }
01308     else if( rval != MB_TAG_NOT_FOUND )
01309     {
01310         // dense and bit tags might return either MB_TAG_NOT_FOUND or zero bytes.
01311         // sparse tags should always return MB_TAG_NOT_FOUND
01312         CHECK( MB_TAG_SPARSE != storage );
01313         std::vector< EntityHandle > expected( del1_range.size(), 0 );
01314         CHECK( expected == tag_data );
01315     }
01316 
01317     // try to get data for deleted list
01318     tag_data.clear();
01319     tag_data.resize( del1_range.size(), (EntityHandle)-1 );
01320     rval = mb.tag_get_data( tag, del1_range, &tag_data[0] );
01321     // if we have a default value, should get that for deleted entities
01322     if( with_default_value )
01323     {
01324         CHECK_ERR( rval );
01325         std::vector< EntityHandle > expected( del1_range.size(), *defval );
01326         CHECK( expected == tag_data );
01327     }
01328     else if( rval != MB_TAG_NOT_FOUND )
01329     {
01330         // dense and bit tags might return either MB_TAG_NOT_FOUND or zero bytes.
01331         // sparse tags should always return MB_TAG_NOT_FOUND
01332         CHECK( MB_TAG_SPARSE != storage );
01333         std::vector< EntityHandle > expected( del1_range.size(), 0 );
01334         CHECK( expected == tag_data );
01335     }
01336 }
01337 
01338 void test_delete_sparse_data()
01339 {
01340     test_delete_tag_data( MB_TAG_DENSE, false );
01341     test_delete_tag_data( MB_TAG_DENSE, true );
01342 }
01343 
01344 void test_delete_dense_data()
01345 {
01346     test_delete_tag_data( MB_TAG_SPARSE, false );
01347     test_delete_tag_data( MB_TAG_SPARSE, true );
01348 }
01349 
01350 void test_delete_bit_data()
01351 {
01352     Core moab;
01353     Interface& mb = moab;
01354     ErrorCode rval;
01355 
01356     // get an entity to set data on
01357     setup_mesh( mb );
01358     Range entities;
01359     rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
01360     CHECK( !entities.empty() );
01361     EntityHandle handle = entities.front();
01362 
01363     // create two tags, one with a default value and one without
01364     unsigned char defval = '\006';  // 110
01365     Tag tag1, tag2;
01366     tag1 = test_create_tag( mb, "tag1", 2, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01367     tag2 = test_create_tag( mb, "tag2", 3, MB_TAG_BIT, MB_TYPE_BIT, &defval );
01368 
01369     // set value for each tag
01370     unsigned char val = '\001';
01371     rval              = mb.tag_set_data( tag1, &handle, 1, &val );CHECK_ERR( rval );
01372     rval = mb.tag_set_data( tag2, &handle, 1, &val );CHECK_ERR( rval );
01373 
01374     // delete both tag values
01375     rval = mb.tag_delete_data( tag1, &handle, 1 );CHECK_ERR( rval );
01376     rval = mb.tag_delete_data( tag2, &handle, 1 );CHECK_ERR( rval );
01377 
01378     // try to get value for tag w/out default.
01379     // should get back either not found, or a zero value.
01380     val  = 0xFF;
01381     rval = mb.tag_get_data( tag1, &handle, 1, &val );
01382     if( MB_SUCCESS == rval )
01383         CHECK_EQUAL( val, '\0' );
01384     else
01385         CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01386 
01387     // test that we get back default value for second tag
01388     val  = 0xFF;
01389     rval = mb.tag_get_data( tag2, &handle, 1, &val );CHECK_ERR( rval );
01390     CHECK_EQUAL( defval, val );
01391 }
01392 
01393 void test_get_set_variable_length( const char* name, TagType storage, DataType type, const void** values,
01394                                    const int* lengths, int num_values, const void* default_value,
01395                                    int default_value_length )
01396 {
01397     std::vector< const void* > data;
01398     std::vector< int > data_lens;
01399 
01400     // create mesh and tag
01401     Core moab;
01402     Interface& mb = moab;
01403     setup_mesh( mb );
01404     Tag tag = test_create_var_len_tag( mb, name, storage, type, default_value, default_value_length );
01405 
01406     // get some handles to work with
01407     Range entities;
01408     ErrorCode rval = mb.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
01409     CHECK( !entities.empty() );
01410 
01411     // split handles into four groups
01412     // a) a single handle
01413     // b) some non-consecutive handles in an array
01414     // c) some handles in an Range
01415     // d) remaining handles (remaining in 'entities');
01416     EntityHandle one_handle;
01417     Range::iterator it = entities.begin() += entities.size() / 2;
01418     one_handle         = *it;
01419     entities.erase( it );
01420 
01421     Range handle_range;
01422     std::vector< EntityHandle > handle_list;
01423     for( Range::const_pair_iterator i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i )
01424     {
01425         if( i->first == i->second || i->second - i->first == 1 )
01426         {
01427             EntityHandle h1 = i->first, h2 = i->second;
01428             ++i;
01429             handle_range.insert( h1, h2 );
01430         }
01431         else
01432         {
01433             EntityHandle mid = ( EntityHandle )( i->first + ( i->second - i->first + 1 ) / 2 );
01434             handle_list.push_back( mid );
01435             handle_range.insert( mid + 1, i->second );
01436         }
01437     }
01438     entities = subtract( entities, handle_range );
01439     for( unsigned i = 0; i < handle_list.size(); ++i )
01440         entities.erase( handle_list[i] );
01441 
01442     // try getting/setting single handle value
01443     if( num_values == 1 )
01444         rval = mb.tag_clear_data( tag, &one_handle, 1, values[0], lengths[0] );
01445     else
01446         rval = mb.tag_set_by_ptr( tag, &one_handle, 1, values, lengths );CHECK_ERR( rval );
01447     const void* data_ptr;
01448     int data_len;
01449     rval = mb.tag_get_by_ptr( tag, &one_handle, 1, &data_ptr, &data_len );CHECK_ERR( rval );
01450     CHECK_EQUAL( lengths[0], data_len );
01451     CHECK( !memcmp( values[0], data_ptr, data_len ) );
01452 
01453     int typesize = 0;
01454     switch( type )
01455     {
01456         case MB_TYPE_INTEGER:
01457             typesize = sizeof( int );
01458             break;
01459         case MB_TYPE_DOUBLE:
01460             typesize = sizeof( double );
01461             break;
01462         case MB_TYPE_HANDLE:
01463             typesize = sizeof( EntityHandle );
01464             break;
01465         case MB_TYPE_BIT:
01466             typesize = 1;
01467             break;
01468         case MB_TYPE_OPAQUE:
01469             typesize = 1;
01470             break;
01471     }
01472 
01473     // try getting/setting for arrays of handles
01474 
01475     int count, step;
01476     if( num_values == 1 )
01477     {
01478         count = handle_list.size();
01479         step  = 0;
01480         rval  = mb.tag_clear_data( tag, &handle_list[0], count, values[0], lengths[0] );
01481     }
01482     else
01483     {
01484         count = std::min( (int)handle_list.size(), num_values );
01485         step  = 1;
01486         rval  = mb.tag_set_by_ptr( tag, &handle_list[0], count, values, lengths );
01487     }
01488     CHECK_ERR( rval );
01489     data.clear();
01490     data.resize( count, 0 );
01491     data_lens.clear();
01492     data_lens.resize( count, 0 );
01493     rval = mb.tag_get_by_ptr( tag, &handle_list[0], count, &data[0], &data_lens[0] );CHECK_ERR( rval );
01494     for( int i = 0; i < count; ++i )
01495     {
01496         CHECK_EQUAL( lengths[i * step], data_lens[i] );
01497         CHECK( NULL != data[i] );
01498         CHECK( !memcmp( values[i], data[i * step], typesize * lengths[i * step] ) );
01499     }
01500 
01501     // try getting/setting for Range of handles
01502 
01503     if( num_values > 1 )
01504     {
01505         data.resize( num_values );
01506         data_lens.resize( num_values );
01507         std::copy( values, values + num_values, data.begin() );
01508         std::copy( lengths, lengths + num_values, data_lens.begin() );
01509         while( data.size() < handle_range.size() )
01510         {
01511             size_t s = data.size();
01512             data.resize( 2 * s );
01513             std::copy( data.begin(), data.begin() + s, data.begin() + s );
01514             data_lens.resize( 2 * s );
01515             std::copy( data_lens.begin(), data_lens.begin() + s, data_lens.begin() + s );
01516         }
01517         rval = mb.tag_set_by_ptr( tag, handle_range, &data[0], &data_lens[0] );
01518     }
01519     else
01520     {
01521         rval = mb.tag_clear_data( tag, handle_range, values[0], lengths[0] );
01522     }
01523     CHECK_ERR( rval );
01524 
01525     data.clear();
01526     data.resize( handle_range.size(), 0 );
01527     data_lens.clear();
01528     data_lens.resize( handle_range.size(), 0 );
01529     rval = mb.tag_get_by_ptr( tag, handle_range, &data[0], &data_lens[0] );CHECK_ERR( rval );
01530 
01531     for( size_t i = 0; i < data.size(); ++i )
01532     {
01533         const void* expect = values[( i * step ) % num_values];
01534         int expect_len     = lengths[( i * step ) % num_values];
01535         CHECK_EQUAL( expect_len, data_lens[i] );
01536         CHECK( NULL != data[i] );
01537         CHECK( !memcmp( expect, data[i], expect_len * typesize ) );
01538     }
01539 
01540     // try getting unset values
01541 
01542     data.resize( entities.size() );
01543     data_lens.resize( entities.size() );
01544     rval = mb.tag_get_by_ptr( tag, entities, &data[0], &data_lens[0] );
01545     // if there was a default value, we should have gotten it for all unset entities
01546     if( default_value )
01547     {
01548         CHECK_ERR( rval );
01549         for( unsigned i = 0; i < entities.size(); ++i )
01550         {
01551             CHECK_EQUAL( default_value_length, data_lens[i] );
01552             CHECK( NULL != data[i] );
01553             CHECK( !memcmp( default_value, data[i], typesize * default_value_length ) );
01554         }
01555     }
01556     // otherwise we should get MB_TAG_NOT_FOUND
01557     else
01558     {
01559         CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
01560     }
01561 
01562     // Check that handles for other entities didn't change.
01563 
01564     // one handle
01565     rval = mb.tag_get_by_ptr( tag, &one_handle, 1, &data_ptr, &data_len );CHECK_ERR( rval );
01566     CHECK_EQUAL( lengths[0], data_len );
01567     CHECK( !memcmp( values[0], data_ptr, typesize * data_len ) );
01568 
01569     // array values
01570     count = std::min( (int)handle_list.size(), num_values );
01571     data.clear();
01572     data.resize( count, 0 );
01573     data_lens.clear();
01574     data_lens.resize( count, 0 );
01575     rval = mb.tag_get_by_ptr( tag, &handle_list[0], count, &data[0], &data_lens[0] );CHECK_ERR( rval );
01576     for( int i = 0; i < count; ++i )
01577     {
01578         CHECK_EQUAL( lengths[i], data_lens[i] );
01579         CHECK( NULL != data[i] );
01580         CHECK( !memcmp( values[i], data[i], typesize * lengths[i] ) );
01581     }
01582 
01583     // range values
01584     data.clear();
01585     data.resize( handle_range.size(), 0 );
01586     data_lens.clear();
01587     data_lens.resize( handle_range.size(), 0 );
01588     rval = mb.tag_get_by_ptr( tag, handle_range, &data[0], &data_lens[0] );CHECK_ERR( rval );
01589 
01590     for( size_t i = 0; i < data.size(); ++i )
01591     {
01592         const void* expect = values[i % num_values];
01593         int expect_len     = lengths[i % num_values];
01594         CHECK_EQUAL( expect_len, data_lens[i] );
01595         CHECK( NULL != data[i] );
01596         CHECK( !memcmp( expect, data[i], typesize * expect_len ) );
01597     }
01598 }
01599 
01600 void test_get_set_variable_length_sparse()
01601 {
01602     const double doubles[14] = { 1, 2, 3, 4, -4, -3, -2, -1, 42, 0, 1974, -0.5, 1. / 3, -1e-10 };
01603     const void* dvals[5]     = { doubles, doubles + 3, doubles + 4, doubles + 8, doubles + 10 };
01604     const int dlens[5]       = { 3, 1, 4, 2, 4 };
01605     test_get_set_variable_length( "vnodef", MB_TAG_SPARSE, MB_TYPE_DOUBLE, dvals, dlens, 5, 0, 0 );
01606 
01607     const int ints[32]   = { 1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15,
01608                            -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 };
01609     const void* ivals[9] = {
01610         ints, ints + 1, ints + 3, ints + 12, ints + 17, ints + 21, ints + 28, ints + 29, ints + 31
01611     };
01612     const int ilens[9]  = { 1, 2, 9, 5, 4, 7, 1, 2, 1 };
01613     const int defvals[] = { 42, 5, 8, 74 };
01614     test_get_set_variable_length( "vdef", MB_TAG_SPARSE, MB_TYPE_INTEGER, ivals, ilens, 9, defvals, 4 );
01615 }
01616 
01617 void test_get_set_variable_length_dense()
01618 {
01619     const double doubles[14] = { 1, 2, 3, 4, -4, -3, -2, -1, 42, 0, 1974, -0.5, 1. / 3, -1e-10 };
01620     const void* dvals[5]     = { doubles, doubles + 3, doubles + 4, doubles + 8, doubles + 10 };
01621     const int dlens[5]       = { 3, 1, 4, 2, 4 };
01622     test_get_set_variable_length( "vnodef", MB_TAG_DENSE, MB_TYPE_DOUBLE, dvals, dlens, 5, 0, 0 );
01623 
01624     const int ints[32]   = { 1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15,
01625                            -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 };
01626     const void* ivals[9] = {
01627         ints, ints + 1, ints + 3, ints + 12, ints + 17, ints + 21, ints + 28, ints + 29, ints + 31
01628     };
01629     const int ilens[9]  = { 1, 2, 9, 5, 4, 7, 1, 2, 1 };
01630     const int defvals[] = { 42, 5, 8, 74 };
01631     test_get_set_variable_length( "vdef", MB_TAG_DENSE, MB_TYPE_INTEGER, ivals, ilens, 9, defvals, 4 );
01632 }
01633 
01634 void test_get_set_variable_length_mesh()
01635 {
01636     Core moab;
01637     Interface& mb = moab;
01638     ErrorCode rval;
01639 
01640     Tag tag       = test_create_var_len_tag( mb, "vmesh", MB_TAG_MESH, MB_TYPE_INTEGER, 0, 0 );
01641     int values1[] = { 6 };
01642     int values5[] = { 1, 2, 3, 4, 5 };
01643 
01644     int one = 1;
01645     const void* data[1];
01646     data[0]                 = values1;
01647     const EntityHandle mesh = 0;
01648     rval                    = mb.tag_set_by_ptr( tag, &mesh, 1, data, &one );CHECK_ERR( rval );
01649 
01650     int len;
01651     rval = mb.tag_get_by_ptr( tag, &mesh, 1, data, &len );CHECK_ERR( rval );
01652     CHECK_EQUAL( 1, len );
01653     CHECK_EQUAL( values1[0], *reinterpret_cast< const int* >( data[0] ) );
01654 
01655     int five = 5;
01656     data[0]  = values5;
01657     rval     = mb.tag_set_by_ptr( tag, &mesh, 1, data, &five );CHECK_ERR( rval );
01658 
01659     rval = mb.tag_get_by_ptr( tag, &mesh, 1, data, &len );CHECK_ERR( rval );
01660     CHECK_EQUAL( 5, len );
01661     CHECK_EQUAL( values5[0], reinterpret_cast< const int* >( data[0] )[0] );
01662     CHECK_EQUAL( values5[1], reinterpret_cast< const int* >( data[0] )[1] );
01663     CHECK_EQUAL( values5[2], reinterpret_cast< const int* >( data[0] )[2] );
01664     CHECK_EQUAL( values5[3], reinterpret_cast< const int* >( data[0] )[3] );
01665     CHECK_EQUAL( values5[4], reinterpret_cast< const int* >( data[0] )[4] );
01666 }
01667 
01668 void test_clear_variable_length( TagType storage )
01669 {
01670     const double doubles[3] = { 1e-1, 1e-2, 1e-3 };
01671     const void* dvals[]     = { doubles };
01672     const int dlen          = sizeof( doubles ) / sizeof( double );
01673     test_get_set_variable_length( "vnodef_clear", storage, MB_TYPE_DOUBLE, dvals, &dlen, 1, 0, 0 );
01674 
01675     const int ints[32]  = { 1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15,
01676                            -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15 };
01677     const void* ivals[] = { ints };
01678     const int ilen      = sizeof( ints ) / sizeof( int );
01679     const int defvals[] = { 42, 5, 8, 74 };
01680     test_get_set_variable_length( "vdef_clear", storage, MB_TYPE_INTEGER, ivals, &ilen, 1, defvals, 4 );
01681 }
01682 
01683 void test_clear_sparse_varlen()
01684 {
01685     test_clear_variable_length( MB_TAG_SPARSE );
01686 }
01687 
01688 void test_clear_dense_varlen()
01689 {
01690     test_clear_variable_length( MB_TAG_DENSE );
01691 }
01692 
01693 void test_get_ents_with_default_value()
01694 {
01695     Core moab;
01696     Interface& mb = moab;
01697     ErrorCode rval;
01698     Range result;
01699 
01700     // create a bunch of vertices
01701     std::vector< double > coords( 90, 0.0 );
01702     Range verts;
01703     rval = mb.create_vertices( &coords[0], coords.size() / 3, verts );CHECK_ERR( rval );
01704     CHECK_EQUAL( coords.size() / 3, (size_t)verts.size() );
01705     // create one edge, which we should never get back from
01706     // our queries with type == MBVERTEX
01707     EntityHandle edge, ends[] = { verts.front(), verts.back() };
01708     rval = mb.create_element( MBEDGE, ends, 2, edge );CHECK_ERR( rval );
01709 
01710     // split vertices into four groups
01711     Range sets[4];
01712     size_t s = 0;
01713     for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
01714     {
01715         sets[s].insert( *i );
01716         s = ( s + 1 ) % 4;
01717     }
01718 
01719     // create a sparse tag and set some verts to non-default value
01720     int default_sparse = 5;
01721     Tag tag_sparse     = test_create_tag( mb, "int", 1, MB_TAG_SPARSE, MB_TYPE_INTEGER, &default_sparse );
01722     std::vector< int > sparse_vals( sets[0].size(), -1 );
01723     rval = mb.tag_set_data( tag_sparse, sets[0], &sparse_vals[0] );CHECK_ERR( rval );
01724 
01725     // get all entities with default value for sparse tag
01726     result.clear();
01727     const void* ptrs[] = { &default_sparse };
01728     rval               = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result );CHECK_ERR( rval );
01729     CHECK_EQUAL( subtract( verts, sets[0] ), result );
01730 
01731     // create a dense tag and set some verts to non-default value
01732     double default_dense = -1.0;
01733     Tag tag_dense        = test_create_tag( mb, "double", 1, MB_TAG_DENSE, MB_TYPE_DOUBLE, &default_dense );
01734     std::vector< double > dense_vals( sets[1].size(), 3.14159 );
01735     rval = mb.tag_set_data( tag_dense, sets[1], &dense_vals[0] );CHECK_ERR( rval );
01736 
01737     // get all entities with default value for dense tag
01738     result.clear();
01739     ptrs[0] = &default_dense;
01740     rval    = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_dense, ptrs, 1, result );CHECK_ERR( rval );
01741     CHECK_EQUAL( subtract( verts, sets[1] ), result );
01742 
01743     // create a variable-length tag and set some verts to non-default value
01744     // SKIP THIS: NO API FOR QUERYING ENTITIES WITH VARIABLE-LENGTH VALUE
01745     // int default_vlen[] = { 1, 2, 3 };
01746     // Tag tag_vlen = test_create_var_len_tag( mb, "vlen", MB_TAG_SPARSE, MB_TYPE_INTEGER,
01747     // default_vlen, sizeof(default_vlen) ); int other_vlen[] = { 4, 5, 6, 7 }; std::vector<const
01748     // void*> vlen_ptrs( sets[2].size(), other_vlen ); std::vector<int> vlen_sizes( sets[2].size)(),
01749     // sizeof(other_vlen) ); rval = mb.tag_set_data( tag_vlen, sets[2], &vlen_ptrs[0],
01750     // &vlen_sizes[0]
01751     // ); CHECK_ERR(rval);
01752 
01753     // check that INTERSECT option works as expected
01754     result.clear();
01755     result.insert( sets[1].front() );
01756     ptrs[0] = &default_sparse;
01757     rval    = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, Interface::INTERSECT );CHECK_ERR( rval );
01758     CHECK_EQUAL( (size_t)1, result.size() );
01759     CHECK_EQUAL( sets[1].front(), result.front() );
01760 
01761     // check that UNITE option works as expected
01762     result.clear();
01763     result.insert( edge );
01764     ptrs[0] = &default_sparse;
01765     rval    = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, Interface::UNION );CHECK_ERR( rval );
01766     CHECK_EQUAL( edge, result.back() );
01767 }
01768 
01769 void test_bit_tag_big()
01770 {
01771     Core moab;
01772     Interface& mb = moab;
01773     ErrorCode rval;
01774     const size_t NUM_VTX = 30000;
01775 
01776     // create a lot of vertices
01777     std::vector< double > coords( 3 * NUM_VTX, 0.0 );
01778     Range verts;
01779     rval = mb.create_vertices( &coords[0], NUM_VTX, verts );CHECK_ERR( rval );
01780     CHECK_EQUAL( NUM_VTX, (size_t)verts.size() );
01781 
01782     // create a bit tag
01783     Tag tag = test_create_tag( mb, "bb", 4, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01784     // for each vertex, store last four bits of handle as tag value
01785     std::vector< unsigned char > values( NUM_VTX );
01786     std::vector< unsigned char >::iterator it = values.begin();
01787     for( Range::iterator j = verts.begin(); j != verts.end(); ++j, ++it )
01788         *it = (unsigned char)( *j & 0xF );
01789     rval = mb.tag_set_data( tag, verts, &values[0] );CHECK_ERR( rval );
01790 
01791     // retrieve values
01792     std::vector< unsigned char > values2( NUM_VTX, 0 );
01793     rval = mb.tag_get_data( tag, verts, &values2[0] );
01794     CHECK_EQUAL( values, values2 );
01795 
01796     // retrieve individual values
01797     it = values.begin();
01798     for( Range::iterator j = verts.begin(); j != verts.end(); ++j, ++it )
01799     {
01800         char value;
01801         rval = mb.tag_get_data( tag, &*j, 1, &value );CHECK_ERR( rval );
01802         CHECK_EQUAL( *it, value );
01803     }
01804 
01805     // retrieve entities
01806     unsigned char value = 0xC;
01807     Range expected, results;
01808     for( Range::reverse_iterator j = verts.rbegin(); j != verts.rend(); ++j )
01809         if( (unsigned char)( *j & 0xF ) == value ) expected.insert( *j );
01810     const void* vals[] = { &value };
01811     rval               = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, vals, 1, results );CHECK_ERR( rval );
01812     CHECK_EQUAL( expected, results );
01813 
01814     // test singe-bit tag
01815     Tag tag1 = test_create_tag( mb, "bb1", 1, MB_TAG_BIT, MB_TYPE_BIT, 0 );
01816     // set tag to 1 on all vertices
01817     values.clear();
01818     values.resize( NUM_VTX, '\001' );
01819     rval = mb.tag_set_data( tag1, verts, &values[0] );CHECK_ERR( rval );
01820     // retrieve values individually
01821     for( Range::iterator j = verts.begin(); j != verts.end(); ++j )
01822     {
01823         char cvalue;
01824         rval = mb.tag_get_data( tag1, &*j, 1, &cvalue );CHECK_ERR( rval );
01825         CHECK_EQUAL( 1, (int)cvalue );
01826     }
01827     // clear values individually
01828     for( Range::iterator j = verts.begin(); j != verts.end(); ++j )
01829     {
01830         char cvalue = '\0';
01831         rval        = mb.tag_set_data( tag1, &*j, 1, &cvalue );CHECK_ERR( rval );
01832     }
01833     // retrieve values using range
01834     rval = mb.tag_get_data( tag1, verts, &values[0] );CHECK_ERR( rval );
01835     size_t first_one = std::find( values.begin(), values.end(), '\001' ) - values.begin();
01836     CHECK_EQUAL( values.size(), first_one );
01837 }
01838 
01839 void setup_mesh( Interface& mb )
01840 {
01841     Range vertex_handles;
01842     const double vertex_coords[] = { 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 2, 1, 0, 0, 2, 0, 1, 2, 0, 2, 2, 0,
01843 
01844                                      0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 0, 2, 1, 1, 2, 1, 2, 2, 1,
01845 
01846                                      0, 0, 2, 1, 0, 2, 2, 0, 2, 0, 1, 2, 1, 1, 2, 2, 1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2 };
01847     const unsigned num_vtx       = sizeof( vertex_coords ) / ( 3 * sizeof( double ) );
01848     ErrorCode rval               = mb.create_vertices( vertex_coords, num_vtx, vertex_handles );CHECK_ERR( rval );
01849     CHECK_EQUAL( num_vtx, (unsigned)vertex_handles.size() );
01850 
01851     CHECK_EQUAL( 27u, num_vtx );
01852     EntityHandle elements[8];
01853     EntityHandle conn[8][8] = { { 0, 1, 4, 3, 9, 10, 13, 12 },      { 1, 2, 5, 4, 10, 11, 14, 13 },
01854                                 { 3, 4, 7, 6, 12, 13, 16, 15 },     { 4, 5, 8, 7, 13, 14, 17, 16 },
01855                                 { 9, 10, 13, 12, 18, 19, 22, 21 },  { 10, 11, 14, 13, 19, 20, 23, 22 },
01856                                 { 12, 13, 16, 15, 21, 22, 25, 24 }, { 13, 14, 17, 16, 22, 23, 26, 25 } };
01857     for( unsigned i = 0; i < 8; ++i )
01858     {
01859         rval = mb.create_element( MBHEX, conn[i], 8, elements[i] );CHECK_ERR( rval );
01860     }
01861 
01862     // delete some stuff so there are multiple sequences
01863     rval = mb.delete_entities( elements + 2, 2 );CHECK_ERR( rval );
01864     Range::iterator i = vertex_handles.begin();
01865     i += 16;
01866     rval = mb.delete_entities( &*i, 1 );CHECK_ERR( rval );
01867     i += 2;
01868     rval = mb.delete_entities( &*i, 1 );CHECK_ERR( rval );
01869 }
01870 
01871 /* Found bug where last entity in sequence is not
01872    returned for get entity by tag for a variable-
01873    length tag.  Test to make sure that it remains
01874    fixed.
01875  */
01876 void regression_one_entity_by_var_tag()
01877 {
01878     Core moab;
01879     ErrorCode rval;
01880 
01881     EntityHandle vertex;
01882     const double coords[] = { 0, 0, 0 };
01883     rval                  = moab.create_vertex( coords, vertex );CHECK_ERR( rval );
01884 
01885     Tag tag;
01886     rval = moab.tag_get_handle( "testtag", 0, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_VARLEN | MB_TAG_EXCL );CHECK_ERR( rval );
01887 
01888     int taglen            = 1;
01889     const void* ptrarr[1] = { &taglen };
01890     rval                  = moab.tag_set_by_ptr( tag, &vertex, 1, ptrarr, &taglen );CHECK_ERR( rval );
01891 
01892     Range ents;
01893     rval = moab.get_entities_by_type_and_tag( 0, MBVERTEX, &tag, 0, 1, ents );CHECK_ERR( rval );
01894 
01895     CHECK_EQUAL( (size_t)1, ents.size() );
01896     CHECK_EQUAL( vertex, ents.front() );
01897 }
01898 
01899 /* Return MB_ENTITY_NOT_FOUND if asked to set a tag on an
01900    entity that doesn't exist.
01901  */
01902 void regression_tag_on_nonexistent_entity()
01903 {
01904     Core moab;
01905     ErrorCode rval;
01906     const int tagval      = 0xdeadbeef;
01907     const void* valarr[1] = { &tagval };
01908     const int numval      = 1;
01909 
01910     // create all three types of tags
01911     Tag dense, sparse, bit;
01912     rval = moab.tag_get_handle( "test_dense", 1, MB_TYPE_INTEGER, dense, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
01913     rval = moab.tag_get_handle( "test_sparse", 1, MB_TYPE_INTEGER, sparse, MB_TAG_SPARSE | MB_TAG_EXCL );CHECK_ERR( rval );
01914     rval = moab.tag_get_handle( "test_bit", 4, MB_TYPE_BIT, bit, MB_TAG_EXCL );CHECK_ERR( rval );
01915 
01916     // for each tag type, check all four mechanisms for setting tag data
01917     // (fixed and variable length given array or range).
01918     EntityHandle handle = (EntityHandle)1;
01919     Range handles;
01920     handles.insert( handle );
01921 
01922     rval = moab.tag_set_data( dense, &handle, 1, &tagval );
01923     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01924     rval = moab.tag_set_data( sparse, &handle, 1, &tagval );
01925     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01926     rval = moab.tag_set_data( bit, &handle, 1, &tagval );
01927     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01928 
01929     rval = moab.tag_set_data( dense, handles, &tagval );
01930     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01931     rval = moab.tag_set_data( sparse, handles, &tagval );
01932     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01933     rval = moab.tag_set_data( bit, handles, &tagval );
01934     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01935 
01936     rval = moab.tag_set_by_ptr( dense, &handle, 1, valarr, &numval );
01937     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01938     rval = moab.tag_set_by_ptr( sparse, &handle, 1, valarr, &numval );
01939     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01940 
01941     rval = moab.tag_set_by_ptr( dense, handles, valarr, &numval );
01942     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01943     rval = moab.tag_set_by_ptr( sparse, handles, valarr, &numval );
01944     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01945 
01946     // now add create an entity and try an adjacent handle
01947     EntityHandle set;
01948     rval = moab.create_meshset( 0, set );CHECK_ERR( rval );
01949 
01950     handle = ( EntityHandle )( set + 1 );
01951     handles.clear();
01952     handles.insert( handle );
01953 
01954     rval = moab.tag_set_data( dense, &handle, 1, &tagval );
01955     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01956     rval = moab.tag_set_data( sparse, &handle, 1, &tagval );
01957     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01958     rval = moab.tag_set_data( bit, &handle, 1, &tagval );
01959     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01960 
01961     rval = moab.tag_set_data( dense, handles, &tagval );
01962     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01963     rval = moab.tag_set_data( sparse, handles, &tagval );
01964     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01965     rval = moab.tag_set_data( bit, handles, &tagval );
01966     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01967 
01968     rval = moab.tag_set_by_ptr( dense, &handle, 1, valarr, &numval );
01969     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01970     rval = moab.tag_set_by_ptr( sparse, &handle, 1, valarr, &numval );
01971     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01972 
01973     rval = moab.tag_set_by_ptr( dense, handles, valarr, &numval );
01974     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01975     rval = moab.tag_set_by_ptr( sparse, handles, valarr, &numval );
01976     CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
01977 }
01978 
01979 void test_tag_iterate_common( TagType storage, bool with_default )
01980 {
01981     // create 1000 vertices
01982     const int NUM_VTX = 1000;
01983     Core moab;
01984     Interface& mb = moab;
01985     std::vector< double > coords( 3 * NUM_VTX );
01986     Range verts, dead;
01987     ErrorCode rval = mb.create_vertices( &coords[0], NUM_VTX, verts );CHECK_ERR( rval );
01988 
01989     // delete about 1% of vertices
01990     const int step    = 100;
01991     int remaining     = NUM_VTX;
01992     Range::iterator i = verts.begin();
01993     for( int j = 0; j < remaining; j += step )
01994     {
01995         rval = mb.delete_entities( &*i, 1 );CHECK_ERR( rval );
01996         dead.insert( *i );
01997         i = verts.erase( i );
01998         i += step - 1;
01999     }
02000 
02001     // Remove some additional values from the range
02002     // so that our handle blocks don't always align with
02003     // sequences
02004     verts.erase( verts.begin() + ( step - 5 ), verts.begin() + ( step + 5 ) );
02005 
02006     // Create an integer tag
02007     Tag tag;
02008     const int defval = 0;
02009     rval = mb.tag_get_handle( "TEST_TAG", 1, MB_TYPE_INTEGER, tag, storage | MB_TAG_CREAT, with_default ? &defval : 0 );CHECK_ERR( rval );
02010 
02011     // Set tag values
02012     std::vector< int > values( verts.size(), defval );
02013     if( !with_default )
02014     {
02015         for( size_t j = 0; j < values.size(); ++j )
02016             values[j] = j;
02017         rval = mb.tag_set_data( tag, verts, &values[0] );CHECK_ERR( rval );
02018     }
02019 
02020     // Check that we get back expected values
02021     i = verts.begin();
02022     void* ptr;
02023     int count, total = 0;
02024     while( i != verts.end() )
02025     {
02026         ptr  = 0;
02027         rval = mb.tag_iterate( tag, i, verts.end(), count, ptr );CHECK_ERR( rval );
02028 
02029         assert( total + count <= (int)verts.size() );
02030         CHECK_ARRAYS_EQUAL( &values[total], count, reinterpret_cast< int* >( ptr ), count );
02031 
02032         if( i == verts.begin() && with_default && storage == MB_TAG_SPARSE ) ( (int*)ptr )[0] = 1.0;
02033 
02034         i += count;
02035         total += count;
02036     }
02037 
02038     // Check that we can set values
02039     i = verts.begin();
02040     while( i != verts.end() )
02041     {
02042         ptr  = 0;
02043         rval = mb.tag_iterate( tag, i, verts.end(), count, ptr );CHECK_ERR( rval );
02044 
02045         Range::iterator end = i + count;
02046         int* arr            = reinterpret_cast< int* >( ptr );
02047         while( end != i )
02048         {
02049             *arr = static_cast< int >( ( *i ) % NUM_VTX );
02050             ++i;
02051             ++arr;
02052         }
02053     }
02054 
02055     // Check that we got back the values that we set
02056     i = verts.begin();
02057     while( i != verts.end() )
02058     {
02059         ptr  = 0;
02060         rval = mb.tag_iterate( tag, i, verts.end(), count, ptr );CHECK_ERR( rval );
02061 
02062         Range::iterator end = i + count;
02063         int* arr            = reinterpret_cast< int* >( ptr );
02064         while( end != i )
02065         {
02066             CHECK_EQUAL( *arr, static_cast< int >( ( *i ) % NUM_VTX ) );
02067             ++i;
02068             ++arr;
02069         }
02070     }
02071 
02072     // Check that we cannot get tag values for invalid handles
02073     rval = mb.tag_iterate( tag, dead.begin(), dead.end(), count, ptr );
02074     CHECK( MB_ENTITY_NOT_FOUND == rval || MB_TAG_NOT_FOUND == rval );
02075 }
02076 void test_tag_iterate_sparse()
02077 {
02078     test_tag_iterate_common( MB_TAG_SPARSE, false );
02079 }
02080 void test_tag_iterate_sparse_default()
02081 {
02082     test_tag_iterate_common( MB_TAG_SPARSE, true );
02083 }
02084 void test_tag_iterate_dense()
02085 {
02086     test_tag_iterate_common( MB_TAG_DENSE, false );
02087 }
02088 void test_tag_iterate_dense_default()
02089 {
02090     test_tag_iterate_common( MB_TAG_DENSE, true );
02091 }
02092 
02093 void test_tag_iterate_invalid()
02094 {
02095     // create 1000 vertices
02096     const int NUM_VTX = 1000;
02097     Core moab;
02098     Interface& mb = moab;
02099     std::vector< double > coords( 3 * NUM_VTX );
02100     Range verts;
02101     ErrorCode rval = mb.create_vertices( &coords[0], NUM_VTX, verts );CHECK_ERR( rval );
02102 
02103     Tag tag;
02104     const int zero = 0;
02105     void* ptr;
02106     int count;
02107 
02108     // Check that we cannot iterate over bit tags
02109     // (this will never be possible because the storage for bit tags
02110     //  is compressed and therefore cannot be directly accessed.)
02111     rval = mb.tag_get_handle( "bits", 1, MB_TYPE_BIT, tag, MB_TAG_EXCL, &zero );CHECK_ERR( rval );
02112     rval = mb.tag_iterate( tag, verts.begin(), verts.end(), count, ptr );
02113     CHECK_EQUAL( MB_TYPE_OUT_OF_RANGE, rval );
02114 
02115     // Check that we cannot iterate over variable-length tags
02116     // (this will never be possible because this API function cannot
02117     //  pass back the length of the tag values)
02118     rval = mb.tag_get_handle( "vden", 1, MB_TYPE_INTEGER, tag, MB_TAG_VARLEN | MB_TAG_DENSE | MB_TAG_EXCL, &zero );CHECK_ERR( rval );
02119     rval = mb.tag_iterate( tag, verts.begin(), verts.end(), count, ptr );
02120     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
02121 
02122     rval = mb.tag_get_handle( "vspr", 1, MB_TYPE_INTEGER, tag, MB_TAG_VARLEN | MB_TAG_SPARSE | MB_TAG_EXCL, &zero );CHECK_ERR( rval );
02123     rval = mb.tag_iterate( tag, verts.begin(), verts.end(), count, ptr );
02124     CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
02125 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines