Sierra Toolkit Version of the Day
UnitTestDataTraits.cpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 
00010 #include <stddef.h>
00011 #include <stdexcept>
00012 #include <sstream>
00013 
00014 #include <stk_util/parallel/Parallel.hpp>
00015 
00016 #include <stk_mesh/base/DataTraits.hpp>
00017 #include <stk_mesh/base/DataTraitsEnum.hpp>
00018 #include <stk_mesh/base/DataTraitsClass.hpp>
00019 
00020 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
00021 
00022 using stk::mesh::DataTraits;
00023 using stk::mesh::data_traits;
00024 using stk::CommAll;
00025 
00026 //----------------------------------------------------------------------
00027 
00028 namespace {
00029 
00030 STKUNIT_UNIT_TEST(TestDataTraits, testVoid)
00031 {
00032   // Test the DataTrait for void
00033 
00034   stk::ParallelMachine pm = MPI_COMM_WORLD;
00035   MPI_Barrier( pm );
00036 
00037   const DataTraits & traits = data_traits<void>();
00038 
00039   STKUNIT_ASSERT(       traits.type_info        == typeid(void) );
00040   STKUNIT_ASSERT_EQUAL( traits.size_of           , size_t(0) );
00041   STKUNIT_ASSERT_EQUAL( traits.alignment_of      , size_t(0) );
00042   STKUNIT_ASSERT_EQUAL( traits.stride_of         , size_t(0) );
00043   STKUNIT_ASSERT_EQUAL( traits.is_void           , true );
00044   STKUNIT_ASSERT_EQUAL( traits.is_integral       , false );
00045   STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false );
00046   STKUNIT_ASSERT_EQUAL( traits.is_array          , false );
00047   STKUNIT_ASSERT_EQUAL( traits.is_pointer        , false );
00048   STKUNIT_ASSERT_EQUAL( traits.is_enum           , false );
00049   STKUNIT_ASSERT_EQUAL( traits.is_class          , false );
00050   STKUNIT_ASSERT_EQUAL( traits.is_pod            , false );
00051   STKUNIT_ASSERT_EQUAL( traits.is_signed         , false );
00052   STKUNIT_ASSERT_EQUAL( traits.is_unsigned       , false );
00053 
00054   STKUNIT_ASSERT( ! traits.remove_pointer   );
00055   STKUNIT_ASSERT( traits.enum_info.empty()  );
00056   STKUNIT_ASSERT( traits.class_info.empty() );
00057 
00058   STKUNIT_ASSERT_THROW( traits.construct( NULL , 0 ) , std::runtime_error );
00059   STKUNIT_ASSERT_THROW( traits.destroy( NULL , 0 ) , std::runtime_error );
00060   STKUNIT_ASSERT_THROW( traits.copy( NULL , NULL , 0 ) , std::runtime_error );
00061   STKUNIT_ASSERT_THROW( traits.sum( NULL , NULL , 0 ) , std::runtime_error );
00062   STKUNIT_ASSERT_THROW( traits.max( NULL , NULL , 0 ) , std::runtime_error );
00063   STKUNIT_ASSERT_THROW( traits.min( NULL , NULL , 0 ) , std::runtime_error );
00064   STKUNIT_ASSERT_THROW( traits.bit_and( NULL, NULL, 0 ), std::runtime_error );
00065   STKUNIT_ASSERT_THROW( traits.bit_or( NULL , NULL, 0 ), std::runtime_error );
00066   STKUNIT_ASSERT_THROW( traits.bit_xor( NULL, NULL, 0 ), std::runtime_error );
00067   STKUNIT_ASSERT_THROW( traits.print( std::cout, NULL, 0), std::runtime_error);
00068 
00069   CommAll comm( pm );
00070   STKUNIT_ASSERT_THROW( traits.pack( comm.send_buffer(0) , NULL , 0 ), std::runtime_error );
00071   comm.allocate_buffers( 0 );
00072   comm.communicate();
00073   STKUNIT_ASSERT_THROW( traits.unpack( comm.recv_buffer(0) , NULL , 0 ), std::runtime_error );
00074 }
00075 
00076 //----------------------------------------------------------------------
00077 
00078 template< typename T , bool is_integral , bool is_signed >
00079 void test_fundamental_type()
00080 {
00081   // Test DataTrait for fundamental type T
00082 
00083   stk::ParallelMachine pm = MPI_COMM_WORLD;
00084   int p_rank = stk::parallel_machine_rank( pm );
00085   int p_size = stk::parallel_machine_size( pm );
00086   MPI_Barrier( pm );
00087 
00088   // Test data trait properties of type T
00089   const DataTraits & traits = data_traits<T>();
00090   STKUNIT_ASSERT(       traits.type_info        == typeid(T) );
00091   STKUNIT_ASSERT_EQUAL( traits.size_of           , sizeof(T) );
00092   STKUNIT_ASSERT_EQUAL( traits.alignment_of      , sizeof(T) );
00093   STKUNIT_ASSERT_EQUAL( traits.stride_of         , sizeof(T) );
00094   STKUNIT_ASSERT_EQUAL( traits.is_void           , false );
00095   STKUNIT_ASSERT_EQUAL( traits.is_integral       , is_integral );
00096   STKUNIT_ASSERT_EQUAL( traits.is_floating_point , ! is_integral );
00097   STKUNIT_ASSERT_EQUAL( traits.is_array          , false );
00098   STKUNIT_ASSERT_EQUAL( traits.is_pointer        , false );
00099   STKUNIT_ASSERT_EQUAL( traits.is_enum           , false );
00100   STKUNIT_ASSERT_EQUAL( traits.is_class          , false );
00101   STKUNIT_ASSERT_EQUAL( traits.is_pod            , true );
00102   STKUNIT_ASSERT_EQUAL( traits.is_signed         , is_signed );
00103   STKUNIT_ASSERT_EQUAL( traits.is_unsigned       , is_integral && ! is_signed);
00104 
00105   STKUNIT_ASSERT( ! traits.remove_pointer   );
00106   STKUNIT_ASSERT( traits.enum_info.empty()  );
00107   STKUNIT_ASSERT( traits.class_info.empty() );
00108 
00109   const unsigned array_size = 3;
00110   const T a[array_size] = { T(1) , T(2) , T(4) };
00111   T b[array_size] ;
00112 
00113   // Test data trait basic operations on type T
00114   traits.construct( b , array_size );
00115   STKUNIT_ASSERT_EQUAL( T(0) , b[0] );
00116   STKUNIT_ASSERT_EQUAL( T(0) , b[1] );
00117   STKUNIT_ASSERT_EQUAL( T(0) , b[2] );
00118 
00119   traits.copy( b , a , array_size );
00120   STKUNIT_ASSERT_EQUAL( T(1) , b[0] );
00121   STKUNIT_ASSERT_EQUAL( T(2) , b[1] );
00122   STKUNIT_ASSERT_EQUAL( T(4) , b[2] );
00123 
00124   traits.sum( b , a , array_size );
00125   STKUNIT_ASSERT_EQUAL( T(2) , b[0] );
00126   STKUNIT_ASSERT_EQUAL( T(4) , b[1] );
00127   STKUNIT_ASSERT_EQUAL( T(8) , b[2] );
00128 
00129   traits.min( b , a , array_size );
00130   STKUNIT_ASSERT_EQUAL( T(1) , b[0] );
00131   STKUNIT_ASSERT_EQUAL( T(2) , b[1] );
00132   STKUNIT_ASSERT_EQUAL( T(4) , b[2] );
00133 
00134   traits.sum( b , a , array_size );
00135   traits.max( b , a , array_size );
00136   STKUNIT_ASSERT_EQUAL( T(2) , b[0] );
00137   STKUNIT_ASSERT_EQUAL( T(4) , b[1] );
00138   STKUNIT_ASSERT_EQUAL( T(8) , b[2] );
00139 
00140   if ( is_integral ) {
00141     // Test integral-specific operations
00142     traits.bit_or( b , a , array_size );
00143     STKUNIT_ASSERT_EQUAL( T(3) , b[0] );
00144     STKUNIT_ASSERT_EQUAL( T(6) , b[1] );
00145     STKUNIT_ASSERT_EQUAL( T(12) , b[2] );
00146 
00147     traits.bit_and( b , a , array_size );
00148     STKUNIT_ASSERT_EQUAL( T(1) , b[0] );
00149     STKUNIT_ASSERT_EQUAL( T(2) , b[1] );
00150     STKUNIT_ASSERT_EQUAL( T(4) , b[2] );
00151 
00152     traits.bit_xor( b , a , array_size );
00153     STKUNIT_ASSERT_EQUAL( T(0) , b[0] );
00154     STKUNIT_ASSERT_EQUAL( T(0) , b[1] );
00155     STKUNIT_ASSERT_EQUAL( T(0) , b[2] );
00156   }
00157   else {
00158     // Test unsupported operations
00159     STKUNIT_ASSERT_THROW(traits.bit_or (b, a, array_size), std::runtime_error);
00160     STKUNIT_ASSERT_THROW(traits.bit_and(b, a, array_size), std::runtime_error);
00161     STKUNIT_ASSERT_THROW(traits.bit_xor(b, a, array_size), std::runtime_error);
00162   }
00163 
00164   // Test data trait pack/unpack (communication) of type T
00165   traits.construct( b , array_size );
00166   CommAll comm( pm );
00167   traits.pack( comm.send_buffer(0) , a , array_size );
00168   comm.allocate_buffers( 0 );
00169   traits.pack( comm.send_buffer(0) , a , array_size );
00170   comm.communicate();
00171   if (p_rank == 0) {
00172     for (int proc_id = 0; proc_id < p_size; ++proc_id) {
00173       traits.unpack( comm.recv_buffer(proc_id) , b , array_size );
00174       STKUNIT_ASSERT_EQUAL( T(1) , b[0] );
00175       STKUNIT_ASSERT_EQUAL( T(2) , b[1] );
00176       STKUNIT_ASSERT_EQUAL( T(4) , b[2] );
00177     }
00178   }
00179 
00180   // Test data trait print of type T
00181   std::ostringstream oss;
00182   oss << traits.name << " " ;
00183   traits.print( oss , a , array_size );
00184   oss << std::endl ;
00185 
00186   // Test data trait destruction (no-op in this case)
00187   traits.destroy( b , array_size );
00188 }
00189 
00190 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_bool)
00191 {
00192   test_fundamental_type<char, true, true>();
00193 }
00194 
00195 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedchar)
00196 {
00197   test_fundamental_type<unsigned char, true, false>();
00198 }
00199 
00200 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_short)
00201 {
00202   test_fundamental_type<short, true, true>();
00203 }
00204 
00205 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedshort)
00206 {
00207   test_fundamental_type<unsigned short, true, false>();
00208 }
00209 
00210 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_int)
00211 {
00212   test_fundamental_type<int, true, true>();
00213 }
00214 
00215 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedint)
00216 {
00217   test_fundamental_type<unsigned int, true, false>();
00218 }
00219 
00220 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_long)
00221 {
00222   test_fundamental_type<long, true, true>();
00223 }
00224 
00225 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedlong)
00226 {
00227   test_fundamental_type<unsigned long, true, false>();
00228 }
00229 
00230 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_float)
00231 {
00232   test_fundamental_type<float, false, false>();
00233 }
00234 
00235 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_double)
00236 {
00237   test_fundamental_type<double, false, false>();
00238 }
00239 
00240 //----------------------------------------------------------------------
00241 
00242 template< typename T >
00243 void test_fundamental_pointer()
00244 {
00245   // Test DataTrait for fundamenter pointer type T*
00246 
00247   stk::ParallelMachine pm = MPI_COMM_WORLD;
00248   MPI_Barrier( pm );
00249 
00250   // Test data trait properties of type T*
00251   const DataTraits & traits = data_traits<T*>();
00252   STKUNIT_ASSERT(       traits.type_info        == typeid(T*) );
00253   STKUNIT_ASSERT_EQUAL( traits.size_of           , sizeof(T*) );
00254   STKUNIT_ASSERT_EQUAL( traits.alignment_of      , sizeof(T*) );
00255   STKUNIT_ASSERT_EQUAL( traits.stride_of         , sizeof(T*) );
00256   STKUNIT_ASSERT_EQUAL( traits.is_void           , false );
00257   STKUNIT_ASSERT_EQUAL( traits.is_integral       , false );
00258   STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false );
00259   STKUNIT_ASSERT_EQUAL( traits.is_array          , false );
00260   STKUNIT_ASSERT_EQUAL( traits.is_pointer        , true );
00261   STKUNIT_ASSERT_EQUAL( traits.is_enum           , false );
00262   STKUNIT_ASSERT_EQUAL( traits.is_class          , false );
00263   STKUNIT_ASSERT_EQUAL( traits.is_pod            , false );
00264   STKUNIT_ASSERT_EQUAL( traits.is_signed         , false );
00265   STKUNIT_ASSERT_EQUAL( traits.is_unsigned       , false );
00266 
00267   STKUNIT_ASSERT( traits.remove_pointer == & data_traits<T>()  );
00268   STKUNIT_ASSERT( traits.enum_info.empty()  );
00269   STKUNIT_ASSERT( traits.class_info.empty() );
00270 
00271   const unsigned array_size = 3;
00272   T val[array_size] = { T(1) , T(2) , T(4) };
00273   T * const a[array_size] = { val , val + 1 , val + 2 };
00274   T * b[array_size] ;
00275 
00276   // Test data trait basic operations on type T*
00277   traits.construct( b , array_size );
00278   STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[0] );
00279   STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[1] );
00280   STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[2] );
00281 
00282   traits.copy( b , a , array_size );
00283   STKUNIT_ASSERT_EQUAL( val + 0 , b[0] );
00284   STKUNIT_ASSERT_EQUAL( val + 1 , b[1] );
00285   STKUNIT_ASSERT_EQUAL( val + 2 , b[2] );
00286 
00287   traits.destroy( b , array_size );
00288   STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[0] );
00289   STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[1] );
00290   STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[2] );
00291 
00292   // Test unsupported operations
00293   STKUNIT_ASSERT_THROW(traits.sum    (b, a, array_size),   std::runtime_error);
00294   STKUNIT_ASSERT_THROW(traits.max    (b, a, array_size),   std::runtime_error);
00295   STKUNIT_ASSERT_THROW(traits.min    (b, a, array_size),   std::runtime_error);
00296   STKUNIT_ASSERT_THROW(traits.bit_and(b, a, array_size),   std::runtime_error);
00297   STKUNIT_ASSERT_THROW(traits.bit_or( b, a, array_size),   std::runtime_error);
00298   STKUNIT_ASSERT_THROW(traits.bit_xor(b, a, array_size),   std::runtime_error);
00299   STKUNIT_ASSERT_THROW(traits.print  (std::cout, NULL, 0), std::runtime_error);
00300 
00301   CommAll comm( pm );
00302   STKUNIT_ASSERT_THROW( traits.pack( comm.send_buffer(0) , a , array_size ), std::runtime_error );
00303   comm.allocate_buffers( 0 );
00304   comm.communicate();
00305   STKUNIT_ASSERT_THROW( traits.unpack( comm.recv_buffer(0) , b , array_size ), std::runtime_error );
00306 }
00307 
00308 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_char_ptr)
00309 {
00310   test_fundamental_pointer<char>();
00311 }
00312 
00313 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedchar_ptr)
00314 {
00315   test_fundamental_pointer<unsigned char>();
00316 }
00317 
00318 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_short_ptr)
00319 {
00320   test_fundamental_pointer<short>();
00321 }
00322 
00323 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedshort_ptr)
00324 {
00325   test_fundamental_pointer<unsigned short>();
00326 }
00327 
00328 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_int_ptr)
00329 {
00330   test_fundamental_pointer<int>();
00331 }
00332 
00333 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedint_ptr)
00334 {
00335   test_fundamental_pointer<unsigned int>();
00336 }
00337 
00338 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_long_ptr)
00339 {
00340   test_fundamental_pointer<long>();
00341 }
00342 
00343 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedlong_ptr)
00344 {
00345   test_fundamental_pointer<unsigned long>();
00346 }
00347 
00348 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_float_ptr)
00349 {
00350   test_fundamental_pointer<float>();
00351 }
00352 
00353 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_double_ptr)
00354 {
00355   test_fundamental_pointer<double>();
00356 }
00357 
00358 }
00359 //----------------------------------------------------------------------
00360 
00361 #ifndef __PGI
00362 
00363 enum EType { val_a = 'a' , val_b = 'b' , val_c = 'c' };
00364 
00365 namespace stk {
00366 namespace mesh {
00367 
00368 // This enum will only work within the stk::mesh namespace
00369 DATA_TRAITS_ENUM_3( EType , val_a , val_b , val_c )
00370 
00371 }
00372 }
00373 
00374 namespace {
00375 
00376 STKUNIT_UNIT_TEST(TestDataTraits, testEnum)
00377 {
00378   // Test interaction of DataTraits with enums
00379 
00380   stk::ParallelMachine pm = MPI_COMM_WORLD;
00381   int p_rank = stk::parallel_machine_rank( pm );
00382   int p_size = stk::parallel_machine_size( pm );
00383   MPI_Barrier( pm );
00384 
00385   typedef EType T ;
00386   const DataTraits & traits = data_traits<T>();
00387 
00388   // Test data trait properties of enum type
00389   STKUNIT_ASSERT(       traits.type_info        == typeid(T) );
00390   STKUNIT_ASSERT_EQUAL( traits.size_of           , sizeof(T) );
00391   STKUNIT_ASSERT_EQUAL( traits.alignment_of      , sizeof(T) );
00392   STKUNIT_ASSERT_EQUAL( traits.stride_of         , sizeof(T) );
00393   STKUNIT_ASSERT_EQUAL( traits.is_integral       , false );
00394   STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false );
00395   STKUNIT_ASSERT_EQUAL( traits.is_array          , false );
00396   STKUNIT_ASSERT_EQUAL( traits.is_pointer        , false );
00397   STKUNIT_ASSERT_EQUAL( traits.is_enum           , true );
00398   STKUNIT_ASSERT_EQUAL( traits.is_class          , false );
00399   STKUNIT_ASSERT_EQUAL( traits.is_pod            , true );
00400   STKUNIT_ASSERT_EQUAL( traits.is_signed         , false );
00401   STKUNIT_ASSERT_EQUAL( traits.is_unsigned       , false );
00402 
00403   STKUNIT_ASSERT( ! traits.remove_pointer   );
00404   STKUNIT_ASSERT( traits.class_info.empty() );
00405 
00406   STKUNIT_ASSERT_EQUAL( traits.enum_info.size()   , size_t(3) );
00407   STKUNIT_ASSERT_EQUAL( (traits.enum_info[0].name == "val_a"), true );
00408   STKUNIT_ASSERT_EQUAL( (traits.enum_info[1].name  == "val_b"), true );
00409   STKUNIT_ASSERT_EQUAL( (traits.enum_info[2].name  == "val_c"), true );
00410   STKUNIT_ASSERT_EQUAL( traits.enum_info[0].value , long(val_a) );
00411   STKUNIT_ASSERT_EQUAL( traits.enum_info[1].value , long(val_b) );
00412   STKUNIT_ASSERT_EQUAL( traits.enum_info[2].value , long(val_c) );
00413 
00414   const unsigned array_size = 3;
00415   EType a[array_size] = { val_a , val_b , val_c };
00416   EType b[array_size] ;
00417 
00418   // Test data trait basic operations on enum type
00419   traits.construct( b , array_size );
00420   STKUNIT_ASSERT_EQUAL( val_a , b[0] );
00421   STKUNIT_ASSERT_EQUAL( val_a , b[1] );
00422   STKUNIT_ASSERT_EQUAL( val_a , b[2] );
00423 
00424   traits.copy( b , a , array_size );
00425   STKUNIT_ASSERT_EQUAL( a[0] , b[0] );
00426   STKUNIT_ASSERT_EQUAL( a[1] , b[1] );
00427   STKUNIT_ASSERT_EQUAL( a[2] , b[2] );
00428 
00429   b[0] = val_b ; b[1] = val_b ; b[2] = val_b ;
00430 
00431   traits.min( b , a , array_size );
00432   STKUNIT_ASSERT_EQUAL( val_a , b[0] );
00433   STKUNIT_ASSERT_EQUAL( val_b , b[1] );
00434   STKUNIT_ASSERT_EQUAL( val_b , b[2] );
00435 
00436   b[0] = val_b ; b[1] = val_b ; b[2] = val_b ;
00437 
00438   traits.max( b , a , array_size );
00439   STKUNIT_ASSERT_EQUAL( val_b , b[0] );
00440   STKUNIT_ASSERT_EQUAL( val_b , b[1] );
00441   STKUNIT_ASSERT_EQUAL( val_c , b[2] );
00442 
00443   // Test unsupported operations
00444   STKUNIT_ASSERT_THROW(traits.sum    (b, a, array_size), std::runtime_error);
00445   STKUNIT_ASSERT_THROW(traits.bit_and(b, a, array_size), std::runtime_error);
00446   STKUNIT_ASSERT_THROW(traits.bit_or (b, a, array_size), std::runtime_error);
00447   STKUNIT_ASSERT_THROW(traits.bit_xor(b, a, array_size), std::runtime_error);
00448 
00449   // Test pack/unpack (communication) of enum type
00450   traits.construct( b , array_size );
00451   CommAll comm( pm );
00452   traits.pack( comm.send_buffer(0) , a , array_size );
00453   comm.allocate_buffers( 0 );
00454   traits.pack( comm.send_buffer(0) , a , array_size );
00455   comm.communicate();
00456   if (p_rank == 0) {
00457     for (int proc_id = 0; proc_id < p_size; ++proc_id) {
00458       traits.unpack( comm.recv_buffer(proc_id) , b , array_size );
00459       STKUNIT_ASSERT_EQUAL( a[0] , b[0] );
00460       STKUNIT_ASSERT_EQUAL( a[1] , b[1] );
00461       STKUNIT_ASSERT_EQUAL( a[2] , b[2] );
00462     }
00463   }
00464 
00465   // Test printing of enum type
00466   std::ostringstream oss;
00467   b[2] = static_cast<EType>( 'd' );
00468   oss << traits.name << " " ;
00469   traits.print( oss , b , array_size );
00470   oss << std::endl ;
00471 
00472   // Test destruction of enum type (no-op in this case)
00473   traits.destroy( b , array_size );
00474 }
00475 
00476 }
00477 
00478 //----------------------------------------------------------------------
00479 
00480 struct Vec3 { double x , y , z ; };
00481 
00482 namespace stk {
00483 namespace mesh {
00484 
00485 // This enum will only work within the stk::mesh namespace
00486 DATA_TRAITS_POD_CLASS_3( Vec3 , x , y , z )
00487 
00488 }
00489 }
00490 
00491 namespace {
00492 
00493 STKUNIT_UNIT_TEST(TestDataTraits, testClass)
00494 {
00495   // Test interaction of DataTraits with classes
00496 
00497   stk::ParallelMachine pm = MPI_COMM_WORLD;
00498   int p_rank = stk::parallel_machine_rank( pm );
00499   int p_size = stk::parallel_machine_size( pm );
00500   MPI_Barrier( pm );
00501 
00502   typedef Vec3 T ;
00503   const DataTraits & traits = data_traits<T>();
00504 
00505   // Test data trait properties of class type
00506   STKUNIT_ASSERT(       traits.type_info        == typeid(T) );
00507   STKUNIT_ASSERT_EQUAL( traits.size_of           , sizeof(T) );
00508   STKUNIT_ASSERT_EQUAL( traits.alignment_of      , sizeof(double) );
00509   STKUNIT_ASSERT_EQUAL( traits.stride_of         , sizeof(T) );
00510   STKUNIT_ASSERT_EQUAL( traits.is_integral       , false );
00511   STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false );
00512   STKUNIT_ASSERT_EQUAL( traits.is_array          , false );
00513   STKUNIT_ASSERT_EQUAL( traits.is_pointer        , false );
00514   STKUNIT_ASSERT_EQUAL( traits.is_enum           , false );
00515   STKUNIT_ASSERT_EQUAL( traits.is_class          , true );
00516   STKUNIT_ASSERT_EQUAL( traits.is_pod            , true );
00517   STKUNIT_ASSERT_EQUAL( traits.is_signed         , false );
00518   STKUNIT_ASSERT_EQUAL( traits.is_unsigned       , false );
00519 
00520   STKUNIT_ASSERT( ! traits.remove_pointer   );
00521   STKUNIT_ASSERT( traits.enum_info.empty() );
00522 
00523   const Vec3 a = { 1.0 , 2.0 , 3.0 };
00524   const size_t dx = reinterpret_cast<const unsigned char *>( & a.x ) -
00525                     reinterpret_cast<const unsigned char *>( & a );
00526   const size_t dy = reinterpret_cast<const unsigned char *>( & a.y ) -
00527                     reinterpret_cast<const unsigned char *>( & a );
00528   const size_t dz = reinterpret_cast<const unsigned char *>( & a.z ) -
00529                     reinterpret_cast<const unsigned char *>( & a );
00530 
00531   STKUNIT_ASSERT_EQUAL( traits.class_info.size() , size_t(3) );
00532   STKUNIT_ASSERT_EQUAL( (traits.class_info[0].name == "x"), true );
00533   STKUNIT_ASSERT_EQUAL( (traits.class_info[1].name == "y"), true );
00534   STKUNIT_ASSERT_EQUAL( (traits.class_info[2].name == "z"), true );
00535   STKUNIT_ASSERT_EQUAL( traits.class_info[0].traits, & data_traits<double>() );
00536   STKUNIT_ASSERT_EQUAL( traits.class_info[1].traits, & data_traits<double>() );
00537   STKUNIT_ASSERT_EQUAL( traits.class_info[2].traits, & data_traits<double>() );
00538   STKUNIT_ASSERT_EQUAL( traits.class_info[0].offset, dx );
00539   STKUNIT_ASSERT_EQUAL( traits.class_info[1].offset, dy );
00540   STKUNIT_ASSERT_EQUAL( traits.class_info[2].offset, dz );
00541 
00542   // Test data trait basic operations on class type
00543   const unsigned array_size = 1;
00544   Vec3 b ;
00545   traits.construct( & b , array_size );
00546   traits.copy( & b , & a , array_size );
00547   STKUNIT_ASSERT_EQUAL( b.x , a.x );
00548   STKUNIT_ASSERT_EQUAL( b.y , a.y );
00549   STKUNIT_ASSERT_EQUAL( b.z , a.z );
00550 
00551   // Test unsupport operations on class type
00552   STKUNIT_ASSERT_THROW(traits.sum    (NULL, NULL, 0 ),     std::runtime_error);
00553   STKUNIT_ASSERT_THROW(traits.max    (NULL, NULL, 0 ),     std::runtime_error);
00554   STKUNIT_ASSERT_THROW(traits.min    (NULL, NULL, 0 ),     std::runtime_error);
00555   STKUNIT_ASSERT_THROW(traits.bit_and(NULL, NULL, 0 ),     std::runtime_error);
00556   STKUNIT_ASSERT_THROW(traits.bit_or (NULL, NULL, 0 ),     std::runtime_error);
00557   STKUNIT_ASSERT_THROW(traits.bit_xor(NULL, NULL, 0 ),     std::runtime_error);
00558   STKUNIT_ASSERT_THROW(traits.print  (std::cout, NULL, 0), std::runtime_error);
00559 
00560   // Test data trait pack/unpack (communication) of class type
00561   traits.construct( & b , array_size );
00562   CommAll comm( pm );
00563   traits.pack( comm.send_buffer(0) , & a , array_size );
00564   comm.allocate_buffers( 0 );
00565   traits.pack( comm.send_buffer(0) , & a , array_size );
00566   comm.communicate();
00567   if (p_rank == 0) {
00568     for (int proc_id = 0; proc_id < p_size; ++proc_id) {
00569       traits.unpack( comm.recv_buffer(proc_id) , & b , array_size );
00570       STKUNIT_ASSERT_EQUAL( a.x , b.x );
00571       STKUNIT_ASSERT_EQUAL( a.y , b.y );
00572       STKUNIT_ASSERT_EQUAL( a.z , b.z );
00573     }
00574   }
00575 
00576   traits.destroy( & b , array_size );
00577 }
00578 
00579 }
00580 
00581 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines