diff --git a/include/ebcl/Utilities.hh b/include/ebcl/Utilities.hh index eba08c0..62b6518 100644 --- a/include/ebcl/Utilities.hh +++ b/include/ebcl/Utilities.hh @@ -371,6 +371,35 @@ struct T_BigEndian }; +/*= ARRAY COPYING AND MOVING =================================================*/ + +template< + typename Type , + bool IsTrivial = !std::is_class< Type >( ) +> struct T_ArrayHelpers +{ + // Default-initialise items in an array + static void init( Type* dest , const uint32_t size ); + // Copy-initialise items in an array + static void init( Type* dest , const uint32_t size , Type const& value ); + + // Delete items in an array + static void destroy( Type* dest , const uint32_t size ); + + // Copy array items using copy constructors + static void copyNew( Type const* source , Type* dest , const uint32_t size ); + // Copy array items using assignment operators + static void copyAssign( Type const* source , Type* dest , const uint32_t size ); + + // Initialise destination items using move constructors + static void moveNew( Type* source , Type* dest , const uint32_t size ); + // Move items using assignments + static void moveAssign( Type* source , Type* dest , const uint32_t size ); + // Move items using move constructors and delete source items + static void move( Type* source , Type* dest , const uint32_t size ); +}; + + /*= COMPARATORS AND SORTING ==================================================*/ // F_Comparator< T > - T_Comparator function type diff --git a/include/ebcl/inline/Utilities.hh b/include/ebcl/inline/Utilities.hh index e007559..08d8c37 100644 --- a/include/ebcl/inline/Utilities.hh +++ b/include/ebcl/inline/Utilities.hh @@ -152,6 +152,114 @@ struct T_BigEndian< T , E_Endian::BIG > }; +/*= ARRAY COPYING AND MOVING =================================================*/ + +// Array helpers for trivial types +template< typename T > +struct T_ArrayHelpers< T , true > +{ + static void init( T* dest , const uint32_t size ) + { memset( dest , 0 , size * sizeof( T ) ); } + + static void init( T* dest , const uint32_t size , T const& value ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + ::new ( reinterpret_cast< char* >( &dest[ i ] ) ) T( value ); + } + } + + static void destroy( T* dest , const uint32_t size ) + { M_UNUSED( dest ); M_UNUSED( size ); } + + static void copyNew( T const* source , T* dest , const uint32_t size ) + { memmove( dest , source , sizeof( T ) * size ); } + + static void copyAssign( T const* source , T* dest , const uint32_t size ) + { memmove( dest , source , sizeof( T ) * size ); } + + static void moveNew( T* source , T* dest , const uint32_t size ) + { memmove( dest , source , sizeof( T ) * size ); } + + static void moveAssign( T* source , T* dest , const uint32_t size ) + { memmove( dest , source , sizeof( T ) * size ); } + + static void move( T* source , T* dest , const uint32_t size ) + { memmove( dest , source , sizeof( T ) * size ); } +}; + +/*----------------------------------------------------------------------------*/ + +// Array helpers for non-trivial types +template< typename T > +struct T_ArrayHelpers< T , false > +{ + static void init( T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + ::new ( reinterpret_cast< char* >( &dest[ i ] ) ) T( ); + } + } + + static void init( T* dest , const uint32_t size , T const& value ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + ::new ( reinterpret_cast< char* >( &dest[ i ] ) ) T( value ); + } + } + + // --------------------------------------------------------------------- + + static void destroy( T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + dest[ i ].~T( ); + } + } + + // --------------------------------------------------------------------- + + static void copyNew( T const* source , T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + ::new ( ( char* ) &( dest[ i ] ) ) T( source[ i ] ); + } + } + + static void copyAssign( T const* source , T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + dest[ i ] = source[ i ]; + } + } + + // --------------------------------------------------------------------- + + static void moveNew( T* source , T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + ::new ( reinterpret_cast< char* >( &( dest[ i ] ) ) ) + T( std::move( source[ i ] ) ); + } + } + + static void moveAssign( T* source , T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + dest[ i ] = std::move( source[ i ] ); + } + } + + static void move( T* source , T* dest , const uint32_t size ) + { + for ( uint32_t i = 0 ; i < size ; i ++ ) { + ::new ( reinterpret_cast< char* >( &( dest[ i ] ) ) ) + T( std::move( source[ i ] ) ); + source[ i ].~T( ); + } + } +}; + + /*= COMPARATORS AND SORTING ==================================================*/ template< typename T >