Arrays - Use array helpers

This commit is contained in:
Emmanuel BENOîT 2018-12-15 20:42:54 +01:00
parent 71fee96926
commit c31280325f

View file

@ -33,13 +33,7 @@ inline T_Array< T >::T_Array(
{
if ( capacity_ != 0 ) {
data_ = ( T* )::operator new ( capacity_ * sizeof( T ) );
if ( std::is_class< T >( ) ) {
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
::new ( ( char* ) &( data_[ i ] ) ) T( source[ i ] );
}
} else {
memcpy( data_ , source.data_ , source.size_ * sizeof( T ) );
}
T_ArrayHelpers< T >::copyNew( source.data_ , data_ , source.size_ );
} else {
data_ = nullptr;
}
@ -54,13 +48,7 @@ inline T_Array< T >& T_Array< T >::operator= (
data_ = ( T* )::operator new ( sizeof( T ) * capacity_ );
size_ = other.size_;
growth_ = other.growth_;
if ( std::is_class< T >( ) ) {
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
::new ( ( char* ) &( data_[ i ] ) )T( other[ i ] );
}
} else if ( size_ ) {
memcpy( data_ , other.data_ , size_ * sizeof( T ) );
}
T_ArrayHelpers< T >::copyNew( other.data_ , data_ , other.size_ );
return *this;
}
@ -126,11 +114,7 @@ inline T_Array< T >::~T_Array( )
template< typename T >
inline T_Array< T >& T_Array< T >::clear( ) noexcept
{
if ( std::is_class< T >( ) ) {
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
data_[ i ].~T( );
}
}
T_ArrayHelpers< T >::destroy( data_ , size_ );
size_ = 0;
return *this;
}
@ -181,15 +165,7 @@ inline T_Array< T >& T_Array< T >::ensureCapacity(
const uint32_t mod( capacity % growth_ );
const uint32_t nCap( capacity + ( mod == 0 ? 0 : ( growth_ - mod ) ) );
T* const nData = ( T* )::operator new ( sizeof( T ) * nCap );
if ( std::is_class< T >( ) ) {
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
::new ( reinterpret_cast< char* >( &nData[ i ] ) )
T( std::move( data_[ i ] ) );
data_[ i ].~T( );
}
} else {
memcpy( nData , data_ , size_ * sizeof( T ) );
}
T_ArrayHelpers< T >::move( data_ , nData , size_ );
::operator delete ( (void*) data_ );
capacity_ = nCap;
data_ = nData;
@ -204,9 +180,7 @@ inline T_Array< T >& T_Array< T >::resize(
{
if ( size > size_ ) {
ensureCapacity( size );
for ( auto i = size_ ; i < size ; i ++ ) {
::new ( reinterpret_cast< char* >( &data_[ i ] ) ) T( );
}
T_ArrayHelpers< T >::init( &data_[ size_ ] , size - size_ );
}
size_ = size;
return *this;
@ -220,9 +194,7 @@ inline T_Array< T >& T_Array< T >::resize(
{
if ( size > size_ ) {
ensureCapacity( size );
for ( auto i = size_ ; i < size ; i ++ ) {
::new ( reinterpret_cast< char* >( &data_[ i ] ) ) T( value );
}
T_ArrayHelpers< T >::init( &data_[ size_ ] , size - size_ , value );
}
size_ = size;
return *this;
@ -343,15 +315,12 @@ template< typename T >
inline T_Array< T >& T_Array< T >::addAll(
T_Array< T > const& other ) noexcept
{
if ( other.size_ ) {
ensureCapacity( size_ + other.size_ );
if ( std::is_class< T >( ) ) {
for ( uint32_t i = 0 ; i < other.size_ ; i ++ ) {
::new ( ( char* ) &( data_[ size_ + i ] ) ) T( other.data_[ i ] );
}
} else if ( other.size_ ) {
memcpy( data_ + size_ , other.data_ , sizeof( T ) * other.size_ );
}
T_ArrayHelpers< T >::copyNew(
other.data_ , &data_[ size_ ] , other.size_ );
size_ += other.size_;
}
return *this;
}
@ -359,16 +328,13 @@ template< typename T >
inline T_Array< T >& T_Array< T >::addAll(
T_Array< T >&& other ) noexcept
{
if ( other.size_ ) {
ensureCapacity( size_ + other.size_ );
if ( std::is_class< T >( ) ) {
for ( uint32_t i = 0 ; i < other.size_ ; i ++ ) {
::new ( ( char* ) &( data_[ size_ + i ] ) ) T( std::move( other.data_[ i ] ) );
}
} else if ( other.size_ ) {
memcpy( data_ + size_ , other.data_ , sizeof( T ) * other.size_ );
}
T_ArrayHelpers< T >::moveNew(
other.data_ , &data_[ size_ ] , other.size_ );
size_ += other.size_;
other.size_ = 0;
}
return *this;
}
@ -435,8 +401,8 @@ inline void T_Array< T >::insert(
} else {
ensureCapacity( size_ + 1 );
if ( index < size_ ) {
memmove( &data_[ index + 1 ] , &data_[ index ] ,
sizeof( T ) * ( size_ - index ) );
T_ArrayHelpers< T >::moveAssign( &data_[ index ] ,
&data_[ index + 1 ] , size_ - index );
}
data_[ index ] = item;
size_ ++;
@ -482,14 +448,8 @@ inline void T_Array< T >::remove(
{
assert( index < size_ );
if ( index != size_ - 1 ) {
if ( std::is_class< T >( ) ) {
for ( auto i = index ; i < size_ - 1 ; i ++ ) {
data_[ i ] = std::move( data_[ i + 1 ] );
}
} else {
memmove( &data_[ index ] , &data_[ index + 1 ] ,
( size_ - ( index + 1 ) ) * sizeof( T ) );
}
T_ArrayHelpers< T >::moveAssign( &data_[ index + 1 ] ,
&data_[ index ] , size_ - ( index + 1 ) );
}
data_[ size_ - 1 ].~T( );
size_ --;
@ -548,13 +508,11 @@ inline T_Array< T > T_Array< T >::copyRange(
return T_Array< T >( 1 );
}
// FIXME use memcpy when !std::is_class< T >
const auto l( std::min( last , size_ - 1 ) );
T_Array< T > output( growth_ );
output.ensureCapacity( l - first + 1 );
for ( uint32_t i = first ; i <= l ; i ++ ) {
output.add( data_[ i ] );
}
output.size_ = l - first + 1;
T_ArrayHelpers< T >::copyNew( &data_[ first ] , output.data_ , output.size_ );
return output;
}
@ -567,13 +525,11 @@ inline T_Array< T > T_Array< T >::moveRange(
return T_Array< T >( 1 );
}
// FIXME use memcpy when !std::is_class< T >
const auto l( std::min( last , size_ - 1 ) );
T_Array< T > output( growth_ );
output.ensureCapacity( l - first + 1 );
for ( uint32_t i = first ; i <= l ; i ++ ) {
output.add( std::move( data_[ i ] ) );
}
output.size_ = l - first + 1;
T_ArrayHelpers< T >::moveNew( &data_[ first ] , output.data_ , output.size_ );
return output;
}
@ -1083,14 +1039,10 @@ inline T_StaticArray< T , S >::T_StaticArray(
T_Self const& source ) noexcept
: size_( source.size_ )
{
if ( std::is_class< T >( ) ) {
for ( auto i = 0u ; i < size_ ; i ++ ) {
::new ( (char*) &storage_[ i ] ) T( source[ i ] );
}
} else {
std::memcpy( &storage_ , &source.storage_ ,
size_ * sizeof( T_Storage_ ) );
}
T_ArrayHelpers< T >::copyNew(
reinterpret_cast< T const* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
}
template< typename T , uint32_t S >
@ -1099,14 +1051,10 @@ inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator= (
{
clear( );
size_ = source.size_;
if ( std::is_class< T >( ) ) {
for ( auto i = 0u ; i < size_ ; i ++ ) {
::new ( (char*) &storage_[ i ] ) T( source[ i ] );
}
} else {
std::memcpy( &storage_ , &source.storage_ ,
size_ * sizeof( T_Storage_ ) );
}
T_ArrayHelpers< T >::copyNew(
reinterpret_cast< T const* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
return *this;
}
@ -1117,15 +1065,11 @@ inline T_StaticArray< T , S >::T_StaticArray(
T_Self&& source ) noexcept
: size_( source.size_ )
{
if ( std::is_class< T >( ) ) {
for ( auto i = 0u ; i < size_ ; i ++ ) {
::new ( (char*) &storage_[ i ] ) T( std::move( source[ i ] ) );
}
} else {
std::memcpy( &storage_ , &source.storage_ ,
size_ * sizeof( T_Storage_ ) );
}
source.clear( );
T_ArrayHelpers< T >::move(
reinterpret_cast< T* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
source.size_ = 0;
}
template< typename T , uint32_t S >
@ -1134,15 +1078,11 @@ inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator= (
{
clear( );
size_ = source.size_;
if ( std::is_class< T >( ) ) {
for ( auto i = 0u ; i < size_ ; i ++ ) {
::new ( (char*) &storage_[ i ] ) T( std::move( source[ i ] ) );
}
} else {
std::memcpy( &storage_ , &source.storage_ ,
size_ * sizeof( T_Storage_ ) );
}
source.clear( );
T_ArrayHelpers< T >::move(
reinterpret_cast< T* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
source.size_ = 0;
return *this;
}
@ -1218,7 +1158,7 @@ template< typename T , uint32_t S >
inline T const& T_StaticArray< T , S >::operator[] (
const uint32_t index ) const noexcept
{
assert( index < size_ );
assert( index < size_ && size_ <= S );
return *reinterpret_cast< T const* >( &storage_[ index ] );
}
@ -1321,15 +1261,11 @@ T_StaticArray< T , S >& T_StaticArray< T , S >::addAll(
T_Self const& other ) noexcept
{
assert( size_ + other.size_ <= S );
if ( std::is_class< T >( ) ) {
for ( auto i = 0u ; i < other.size_ ; i ++ , size_ ++ ) {
::new ( (char*) &storage_[ size_ ] ) T( other[ i ] );
}
} else {
memcpy( &storage_[ size_ ] , &other.storage_[ 0 ] ,
other.size_ * sizeof( T_Storage_ ) );
T_ArrayHelpers< T >::copyNew(
reinterpret_cast< T const* >( &other.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ size_ ] ) ,
other.size_ );
size_ += other.size_;
}
return *this;
}
@ -1338,16 +1274,12 @@ T_StaticArray< T , S >& T_StaticArray< T , S >::addAll(
T_Self&& other ) noexcept
{
assert( size_ + other.size_ <= S );
if ( std::is_class< T >( ) ) {
for ( auto i = 0u ; i < other.size_ ; i ++ , size_ ++ ) {
::new ( (char*) &storage_[ size_ ] ) T( std::move( other[ i ] ) );
}
} else {
memcpy( &storage_[ size_ ] , &other.storage_[ 0 ] ,
other.size_ * sizeof( T_Storage_ ) );
T_ArrayHelpers< T >::move(
reinterpret_cast< T* >( &other.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ size_ ] ) ,
other.size_ );
size_ += other.size_;
}
other.clear( );
other.size_ = 0;
return *this;
}
@ -1446,37 +1378,31 @@ template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::remove(
const uint32_t index ) noexcept
{
assert( index < size_ );
assert( index < size_ && size_ <= S );
if ( index != size_ - 1 ) {
if ( std::is_class< T >( ) ) {
for ( auto i = index ; i < size_ - 1 ; i ++ ) {
(*this)[ i ] = std::move( (*this)[ i + 1 ] );
T_ArrayHelpers< T >::moveAssign(
reinterpret_cast< T* >( &storage_[ index + 1 ] ) ,
reinterpret_cast< T* >( &storage_[ index ] ) ,
size_ - ( index + 1 ) );
}
} else {
memmove( &storage_[ index ] , &storage_[ index + 1 ] ,
( size_ - ( index + 1 ) ) * sizeof( T_Storage_ ) );
}
}
(*this)[ size_ - 1 ].~T( );
size_ --;
removeLast( );
}
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::removeSwap(
const uint32_t index ) noexcept
{
assert( index < size_ );
assert( index < size_ && size_ <= S );
if ( index != size_ - 1 ) {
(*this)[ index ] = std::move( (*this)[ size_ - 1 ] );
}
(*this)[ size_ - 1 ].~T( );
size_ --;
removeLast( );
}
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::removeLast( ) noexcept
{
assert( size_ );
assert( size_ && size_ <= S );
(*this)[ size_ - 1 ].~T( );
size_ --;
}
@ -1516,10 +1442,9 @@ inline T_StaticArray< T , S > T_StaticArray< T , S >::copyRange(
const auto l( std::min( last , size_ - 1 ) );
T_StaticArray< T , S > output;
// FIXME use memcpy when !std::is_class< T >
for ( uint32_t i = first ; i <= l ; i ++ ) {
output.add( (*this)[ i ] );
}
output.size_ = l - first + 1;
T_ArrayHelpers< T >::copyNew( &(*this)[ first ] , &output[ 0 ] ,
output.size_ );
return output;
}