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