Sierra Toolkit Version of the Day
DataTraits.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 <cstddef>
00011 #include <stdexcept>
00012 
00013 #include <stk_util/environment/ReportHandler.hpp>
00014 
00015 #include <stk_mesh/base/DataTraits.hpp>
00016 #include <stk_mesh/base/DataTraitsEnum.hpp>
00017 #include <stk_mesh/base/DataTraitsClass.hpp>
00018 
00019 namespace stk {
00020 namespace mesh {
00021 
00022 //----------------------------------------------------------------------
00023 
00024 namespace {
00025 
00026 std::size_t stride( std::size_t size , std::size_t align )
00027 {
00028   if ( align && size % align ) { size += align - size % align ; }
00029   return size ;
00030 }
00031 
00032 }
00033 
00034 DataTraits::DataTraits( const std::type_info & arg_type ,
00035                         const char * const     arg_name ,
00036                         std::size_t            arg_size ,
00037                         std::size_t            arg_align )
00038   : type_info(         arg_type ),
00039     size_of(           arg_size ),
00040     is_void(           false ),
00041     is_integral(       false ),
00042     is_floating_point( false ),
00043     is_pointer(        false ),
00044     is_enum(           false ),
00045     is_class(          false ),
00046     is_pod(            false ),
00047     is_signed(         false ),
00048     is_unsigned(       false ),
00049     alignment_of(      arg_align ),
00050     stride_of(         stride( arg_size , arg_align ) ),
00051     remove_pointer(    NULL ),
00052     name(              arg_name ),
00053     enum_info(),
00054     class_info()
00055 {}
00056 
00057 DataTraits::DataTraits( const std::type_info & arg_type ,
00058                         const DataTraits     & arg_traits )
00059   : type_info(          arg_type ),
00060     size_of(            sizeof(void*) ),
00061     is_void(            false ),
00062     is_integral(        false ),
00063     is_floating_point(  false ),
00064     is_pointer(         true ),
00065     is_enum(            false ),
00066     is_class(           false ),
00067     is_pod(             false ),
00068     is_signed(          false ),
00069     is_unsigned(        false ),
00070     alignment_of(       sizeof(void*) ),
00071     stride_of(          sizeof(void*) ),
00072     remove_pointer( & arg_traits ),
00073     name(),
00074     enum_info(),
00075     class_info()
00076 {
00077   name.assign( arg_traits.name ).append("*");
00078 }
00079 
00080 //----------------------------------------------------------------------
00081 
00082 namespace {
00083 
00084 class DataTraitsVoid : public DataTraits {
00085 public:
00086 
00087   DataTraitsVoid()
00088     : DataTraits( typeid(void) , "void" , 0 , 0 )
00089     { is_void = true ; }
00090 
00091   void construct( void * , std::size_t ) const
00092   { ThrowErrorMsg( "not supported" ); }
00093 
00094   void destroy( void * , std::size_t ) const
00095   { ThrowErrorMsg( "not supported" ); }
00096 
00097   void pack( CommBuffer & , const void * , std::size_t ) const
00098   { ThrowErrorMsg( "not supported" ); }
00099 
00100   void unpack( CommBuffer & , void * , std::size_t ) const
00101   { ThrowErrorMsg( "not supported" ); }
00102 
00103   void print( std::ostream & , const void * , std::size_t ) const
00104   { ThrowErrorMsg( "not supported" ); }
00105 
00106   void copy( void * , const void * , std::size_t ) const
00107   { ThrowErrorMsg( "not supported" ); }
00108 
00109   void sum( void * , const void * , std::size_t ) const
00110   { ThrowErrorMsg( "not supported" ); }
00111 
00112   void max( void * , const void * , std::size_t ) const
00113   { ThrowErrorMsg( "not supported" ); }
00114 
00115   void min( void * , const void * , std::size_t ) const
00116   { ThrowErrorMsg( "not supported" ); }
00117 
00118   virtual void bit_and( void * , const void * , std::size_t ) const
00119   { ThrowErrorMsg( "not supported" ); }
00120 
00121   virtual void bit_or( void * , const void * , std::size_t ) const
00122   { ThrowErrorMsg( "not supported" ); }
00123 
00124   virtual void bit_xor( void * , const void * , std::size_t ) const
00125   { ThrowErrorMsg( "not supported" ); }
00126 };
00127 
00128 }
00129 
00130 template<> const DataTraits & data_traits<void>()
00131 { static const DataTraitsVoid traits ; return traits ; }
00132 
00133 //----------------------------------------------------------------------
00134 
00135 namespace {
00136 
00137 template< typename A , typename B >
00138 struct IsSameType { enum { value = false }; };
00139 
00140 template< typename A >
00141 struct IsSameType<A,A> { enum { value = true }; };
00142 
00143 
00144 template< typename T >
00145 class DataTraitsCommon : public DataTraits {
00146 public:
00147 
00148   explicit DataTraitsCommon( const char * arg_name )
00149     : DataTraits( typeid(T) , arg_name , sizeof(T) , sizeof(T) )
00150   {
00151     is_pod            = true ;
00152 
00153     is_integral       = IsSameType<T,char>::value ||
00154                         IsSameType<T,unsigned char>::value ||
00155                         IsSameType<T,short>::value ||
00156                         IsSameType<T,unsigned short>::value ||
00157                         IsSameType<T,int>::value ||
00158                         IsSameType<T,unsigned int>::value ||
00159                         IsSameType<T,long>::value ||
00160                         IsSameType<T,unsigned long>::value ;
00161 
00162     is_signed         = IsSameType<T,char>::value ||
00163                         IsSameType<T,short>::value ||
00164                         IsSameType<T,int>::value ||
00165                         IsSameType<T,long>::value ;
00166 
00167     is_unsigned       = IsSameType<T,unsigned char>::value ||
00168                         IsSameType<T,unsigned short>::value ||
00169                         IsSameType<T,unsigned int>::value ||
00170                         IsSameType<T,unsigned long>::value ;
00171 
00172     is_floating_point = IsSameType<T,double>::value ||
00173                         IsSameType<T,float>::value ;
00174   }
00175 
00176   void construct( void * v , std::size_t n ) const
00177   {
00178     T * x = reinterpret_cast<T*>( v );
00179     T * const x_end = x + n ;
00180     while ( x_end != x ) { *x++ = 0 ; }
00181   }
00182 
00183   void destroy( void * v , std::size_t n ) const {}
00184 
00185   void pack( CommBuffer & buf , const void * v , std::size_t n ) const
00186   {
00187     const T * x = reinterpret_cast<const T*>( v );
00188     buf.pack<T>( x , n );
00189   }
00190 
00191   void unpack( CommBuffer & buf , void * v , std::size_t n ) const
00192   {
00193     T * x = reinterpret_cast<T*>( v );
00194     buf.unpack<T>( x , n );
00195   }
00196 
00197   void copy( void * vx , const void * vy , std::size_t n ) const
00198   {
00199     const T * y = reinterpret_cast<const T*>( vy );
00200     T * x = reinterpret_cast<T*>( vx );
00201     T * const x_end = x + n ;
00202     while ( x_end != x ) { *x++ = *y++ ; };
00203   }
00204 
00205   void sum( void * vx , const void * vy , std::size_t n ) const
00206   {
00207     const T * y = reinterpret_cast<const T*>( vy );
00208     T * x = reinterpret_cast<T*>( vx );
00209     T * const x_end = x + n ;
00210     while ( x_end != x ) { *x++ += *y++ ; };
00211   }
00212 
00213   virtual void print( std::ostream & s , const void * v , std::size_t n ) const
00214   {
00215     if ( n ) {
00216       const T * x = reinterpret_cast<const T*>( v );
00217       const T * const x_end = x + n ;
00218       s << *x++ ;
00219       while ( x_end != x ) { s << " " << *x++ ; }
00220     }
00221   }
00222 
00223   virtual void max( void * vx , const void * vy , std::size_t n ) const
00224   { ThrowErrorMsg( "not supported" ); }
00225 
00226   virtual void min( void * vx , const void * vy , std::size_t n ) const
00227   { ThrowErrorMsg( "not supported" ); }
00228 
00229   virtual void bit_and( void * , const void * , std::size_t ) const
00230   { ThrowErrorMsg( "not supported" ); }
00231 
00232   virtual void bit_or( void * , const void * , std::size_t ) const
00233   { ThrowErrorMsg( "not supported" ); }
00234 
00235   virtual void bit_xor( void * , const void * , std::size_t ) const
00236   { ThrowErrorMsg( "not supported" ); }
00237 };
00238 
00239 template< typename T >
00240 class DataTraitsNumeric : public DataTraitsCommon<T> {
00241 public:
00242 
00243   explicit DataTraitsNumeric( const char * arg_name )
00244     : DataTraitsCommon<T>( arg_name )  {}
00245 
00246   virtual void max( void * vx , const void * vy , std::size_t n ) const
00247   {
00248     const T * y = reinterpret_cast<const T*>( vy );
00249     T * x = reinterpret_cast<T*>( vx );
00250     T * const x_end = x + n ;
00251     for ( ; x_end != x ; ++x , ++y ) { if ( *x < *y ) { *x = *y ; } }
00252   }
00253 
00254   virtual void min( void * vx , const void * vy , std::size_t n ) const
00255   {
00256     const T * y = reinterpret_cast<const T*>( vy );
00257     T * x = reinterpret_cast<T*>( vx );
00258     T * const x_end = x + n ;
00259     for ( ; x_end != x ; ++x , ++y ) { if ( *x > *y ) { *x = *y ; } }
00260   }
00261 };
00262 
00263 template< typename T >
00264 class DataTraitsComplex : public DataTraitsCommon<T> {
00265 public:
00266 
00267   explicit DataTraitsComplex( const char * arg_name )
00268     : DataTraitsCommon<T>( arg_name ) {}
00269 };
00270 
00271 template< typename T >
00272 class DataTraitsIntegral : public DataTraitsNumeric<T> {
00273 public:
00274   DataTraitsIntegral( const char * name ) : DataTraitsNumeric<T>( name ) {}
00275 
00276   virtual void bit_and( void * vx , const void * vy , std::size_t n ) const
00277   {
00278     const T * y = reinterpret_cast<const T*>( vy );
00279     T * x = reinterpret_cast<T*>( vx );
00280     T * const x_end = x + n ;
00281     while ( x_end != x ) { *x++ &= *y++ ; }
00282   }
00283 
00284   virtual void bit_or( void * vx , const void * vy , std::size_t n ) const
00285   {
00286     const T * y = reinterpret_cast<const T*>( vy );
00287     T * x = reinterpret_cast<T*>( vx );
00288     T * const x_end = x + n ;
00289     while ( x_end != x ) { *x++ |= *y++ ; }
00290   }
00291 
00292   virtual void bit_xor( void * vx , const void * vy , std::size_t n ) const
00293   {
00294     const T * y = reinterpret_cast<const T*>( vy );
00295     T * x = reinterpret_cast<T*>( vx );
00296     T * const x_end = x + n ;
00297     while ( x_end != x ) { *x++ ^= *y++ ; }
00298   }
00299 };
00300 
00301 class DataTraitsChar : public DataTraitsIntegral<char> {
00302 public:
00303   DataTraitsChar() : DataTraitsIntegral<char>( "char" ) {}
00304 
00305   virtual void print( std::ostream & s , const void * v , std::size_t n ) const
00306   {
00307     if ( n ) {
00308       const char * x = reinterpret_cast<const char*>( v );
00309       const char * const x_end = x + n ;
00310       s << int(*x++) ;
00311       while ( x_end != x ) { s << " " << int(*x++) ; }
00312     }
00313   }
00314 };
00315 
00316 class DataTraitsUnsignedChar : public DataTraitsIntegral<unsigned char> {
00317 public:
00318   DataTraitsUnsignedChar()
00319     : DataTraitsIntegral<unsigned char>( "unsigned char" ) {}
00320 
00321   virtual void print( std::ostream & s , const void * v , std::size_t n ) const
00322   {
00323     if ( n ) {
00324       const unsigned char * x = reinterpret_cast<const unsigned char*>( v );
00325       const unsigned char * const x_end = x + n ;
00326       s << unsigned(*x++) ;
00327       while ( x_end != x ) { s << " " << unsigned(*x++) ; }
00328     }
00329   }
00330 };
00331 
00332 }
00333 
00334 #define DATA_TRAITS_NUMERIC( T )        \
00335 template<>      \
00336 const DataTraits & data_traits<T>()     \
00337 { static const DataTraitsNumeric<T> traits( #T ); return traits ; }
00338 
00339 #define DATA_TRAITS_COMPLEX( T )        \
00340 template<>      \
00341 const DataTraits & data_traits<T>()     \
00342 { static const DataTraitsComplex<T> traits( #T ); return traits ; }
00343 
00344 #define DATA_TRAITS_INTEGRAL( T )        \
00345 template<>      \
00346 const DataTraits & data_traits<T>()     \
00347 { static const DataTraitsIntegral<T> traits( #T ); return traits ; }
00348 
00349 template<>
00350 const DataTraits & data_traits<char>()
00351 { static const DataTraitsChar traits ; return traits ; }
00352 
00353 template<>
00354 const DataTraits & data_traits<unsigned char>()
00355 { static const DataTraitsUnsignedChar traits ; return traits ; }
00356 
00357 DATA_TRAITS_INTEGRAL( short )
00358 DATA_TRAITS_INTEGRAL( unsigned short )
00359 DATA_TRAITS_INTEGRAL( int )
00360 DATA_TRAITS_INTEGRAL( unsigned int )
00361 DATA_TRAITS_INTEGRAL( long )
00362 DATA_TRAITS_INTEGRAL( unsigned long )
00363 DATA_TRAITS_NUMERIC( float )
00364 DATA_TRAITS_NUMERIC( double )
00365 DATA_TRAITS_COMPLEX( std::complex<float> ) // TODO: Probably not right
00366 DATA_TRAITS_COMPLEX( std::complex<double> ) // TODO: Probably not right
00367 
00368 //----------------------------------------------------------------------
00369 //----------------------------------------------------------------------
00370 
00371 namespace {
00372 
00373 template< typename T >
00374 class DataTraitsPointerToFundamental : public DataTraits {
00375 public:
00376 
00377   DataTraitsPointerToFundamental()
00378     : DataTraits( typeid(T*) , data_traits<T>() ) {}
00379 
00380   void construct( void * v , std::size_t n ) const
00381   {
00382     void ** x = reinterpret_cast<void**>(v);
00383     void ** const x_end = x + n ;
00384     while ( x_end != x ) { *x++ = NULL ; }
00385   }
00386 
00387   void destroy( void * v , std::size_t n ) const
00388   {
00389     void ** x = reinterpret_cast<void**>(v);
00390     void ** const x_end = x + n ;
00391     while ( x_end != x ) { *x++ = NULL ; }
00392   }
00393 
00394   void copy( void * vx , const void * vy , std::size_t n ) const
00395   {
00396     void * const * y = reinterpret_cast<void* const *>(vy);
00397     void ** x = reinterpret_cast<void**>(vx);
00398     void ** const x_end = x + n ;
00399     while ( x_end != x ) { *x++ = *y++ ; }
00400   }
00401 
00402   void pack( CommBuffer & , const void * , std::size_t ) const
00403   { ThrowErrorMsg( "not supported" ); }
00404 
00405   void unpack( CommBuffer & , void * , std::size_t ) const
00406   { ThrowErrorMsg( "not supported" ); }
00407 
00408   void print( std::ostream & , const void * , std::size_t ) const
00409   { ThrowErrorMsg( "not supported" ); }
00410 
00411   void sum( void * , const void * , std::size_t ) const
00412   { ThrowErrorMsg( "not supported" ); }
00413 
00414   void max( void * , const void * , std::size_t ) const
00415   { ThrowErrorMsg( "not supported" ); }
00416 
00417   void min( void * , const void * , std::size_t ) const
00418   { ThrowErrorMsg( "not supported" ); }
00419 
00420   virtual void bit_and( void * , const void * , std::size_t ) const
00421   { ThrowErrorMsg( "not supported" ); }
00422 
00423   virtual void bit_or( void * , const void * , std::size_t ) const
00424   { ThrowErrorMsg( "not supported" ); }
00425 
00426   virtual void bit_xor( void * , const void * , std::size_t ) const
00427   { ThrowErrorMsg( "not supported" ); }
00428 };
00429 
00430 }
00431 
00432 #define DATA_TRAITS_POINTER( T )        \
00433 template<> const DataTraits & data_traits<T*>()  \
00434 { static const DataTraitsPointerToFundamental<T> traits ; return traits ; }
00435 
00436 DATA_TRAITS_POINTER( char )
00437 DATA_TRAITS_POINTER( unsigned char )
00438 DATA_TRAITS_POINTER( short )
00439 DATA_TRAITS_POINTER( unsigned short )
00440 DATA_TRAITS_POINTER( int )
00441 DATA_TRAITS_POINTER( unsigned int )
00442 DATA_TRAITS_POINTER( long )
00443 DATA_TRAITS_POINTER( unsigned long )
00444 DATA_TRAITS_POINTER( float )
00445 DATA_TRAITS_POINTER( double )
00446 DATA_TRAITS_POINTER( void )
00447 DATA_TRAITS_POINTER( std::complex<float> )
00448 DATA_TRAITS_POINTER( std::complex<double> )
00449 
00450 //----------------------------------------------------------------------
00451 
00452 }
00453 }
00454 
00455 
00456 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines