corelib/include/ebcl/inline/Arrays.hh

1567 lines
38 KiB
C++

/******************************************************************************/
/* ARRAYS - INLINE CODE *******************************************************/
/******************************************************************************/
#ifndef _H_EBCL_INLINE_ARRAYS
#define _H_EBCL_INLINE_ARRAYS
#include <ebcl/Arrays.hh>
namespace ebcl {
/*= T_Array ==================================================================*/
template< typename T >
inline T_Array< T >::T_Array( ) noexcept
: T_Array( DEFAULT_GROWTH( ) )
{ }
template< typename T >
inline T_Array< T >::T_Array(
const uint32_t growth ) noexcept
: data_( nullptr ) , capacity_( 0 ) , size_( 0 ) , growth_( growth )
{
assert( growth > 0 );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >::T_Array(
T_Array< T > const& source ) noexcept
: capacity_( source.capacity_ ) , size_( source.size_ ) ,
growth_( source.growth_ )
{
if ( capacity_ != 0 ) {
data_ = ( T* )::operator new ( capacity_ * sizeof( T ) );
T_ArrayHelpers< T >::copyNew( source.data_ , data_ , source.size_ );
} else {
data_ = nullptr;
}
}
template< typename T >
inline T_Array< T >& T_Array< T >::operator= (
T_Array< T > const& other ) noexcept
{
free( );
capacity_ = other.capacity_;
data_ = ( T* )::operator new ( sizeof( T ) * capacity_ );
size_ = other.size_;
growth_ = other.growth_;
T_ArrayHelpers< T >::copyNew( other.data_ , data_ , other.size_ );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >::T_Array(
T_Array< T >&& source ) noexcept
: T_Array( 1 )
{
swap( *this , source );
source.clear( );
}
template< typename T >
inline T_Array< T >& T_Array< T >::operator=(
T_Array< T >&& other ) noexcept
{
swap( *this , other );
other.clear( );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >::T_Array(
std::initializer_list< T > list ) noexcept
: T_Array( DEFAULT_GROWTH( ) )
{
addAll( std::move( list ) );
}
template< typename T >
inline T_Array< T >& T_Array< T >::operator= (
std::initializer_list< T > list ) noexcept
{
clear( );
return addAll( std::move( list ) );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void swap( T_Array< T >& lhs ,
T_Array< T >& rhs ) noexcept
{
using std::swap;
swap( lhs.data_ , rhs.data_ );
swap( lhs.capacity_ , rhs.capacity_ );
swap( lhs.size_ , rhs.size_ );
swap( lhs.growth_ , rhs.growth_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >::~T_Array( )
{
free( );
}
template< typename T >
inline T_Array< T >& T_Array< T >::clear( ) noexcept
{
T_ArrayHelpers< T >::destroy( data_ , size_ );
size_ = 0;
return *this;
}
template< typename T >
inline T_Array< T >& T_Array< T >::free( ) noexcept
{
clear( );
::operator delete ( (void*) data_ );
data_ = nullptr;
capacity_ = 0;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline uint32_t T_Array< T >::capacity( ) const noexcept
{
return capacity_;
}
template< typename T >
inline uint32_t T_Array< T >::size( ) const noexcept
{
return size_;
}
template< typename T >
inline uint32_t T_Array< T >::growth( ) const noexcept
{
return growth_;
}
template< typename T >
inline bool T_Array< T >::empty( ) const noexcept
{
return size_ == 0;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >& T_Array< T >::ensureCapacity(
const uint32_t capacity ) noexcept
{
if ( capacity_ < capacity ) {
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 );
T_ArrayHelpers< T >::move( data_ , nData , size_ );
::operator delete ( (void*) data_ );
capacity_ = nCap;
data_ = nData;
}
return *this;
}
template< typename T >
template< typename Q , typename >
inline T_Array< T >& T_Array< T >::resize(
const uint32_t size )
{
if ( size > size_ ) {
ensureCapacity( size );
T_ArrayHelpers< T >::init( &data_[ size_ ] , size - size_ );
}
size_ = size;
return *this;
}
template< typename T >
template< typename Q , typename >
inline T_Array< T >& T_Array< T >::resize(
const uint32_t size ,
T const& value )
{
if ( size > size_ ) {
ensureCapacity( size );
T_ArrayHelpers< T >::init( &data_[ size_ ] , size - size_ , value );
}
size_ = size;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T& T_Array< T >::operator[] (
const uint32_t index ) noexcept
{
assert( index < size_ );
return data_[ index ];
}
template< typename T >
inline T const& T_Array< T >::operator[] (
const uint32_t index ) const noexcept
{
assert( index < size_ );
return data_[ index ];
}
template< typename T >
inline T& T_Array< T >::last( ) noexcept
{
assert( !empty( ) );
return data_[ size_ - 1 ];
}
template< typename T >
inline T const& T_Array< T >::last( ) const noexcept
{
assert( !empty( ) );
return data_[ size_ - 1 ];
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline int32_t T_Array< T >::indexOf(
T const& item ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( data_[ i ] == item ) {
return i;
}
}
return -1;
}
template< typename T >
inline bool T_Array< T >::contains(
T const& item ) const noexcept
{
return indexOf( item ) != -1;
}
template< typename T >
inline int32_t T_Array< T >::indexOf(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( data_[ i ] ) ) {
return i;
}
}
return -1;
}
template< typename T >
inline bool T_Array< T >::contains(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( data_[ i ] ) ) {
return true;
}
}
return false;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline uint32_t T_Array< T >::add(
T const& item ) noexcept
{
ensureCapacity( size_ + 1 );
::new ( ( char* ) &( data_[ size_ ] ) ) T( item );
return size_ ++;
}
template< typename T >
inline uint32_t T_Array< T >::add(
T&& item ) noexcept
{
ensureCapacity( size_ + 1 );
::new ( ( char* ) &( data_[ size_ ] ) ) T( std::move( item ) );
return size_ ++;
}
/*----------------------------------------------------------------------------*/
template< typename T >
template< typename... Args >
inline T& T_Array< T >::addNew(
Args&& ... args )
{
ensureCapacity( size_ + 1 );
::new ( ( char* ) &( data_[ size_ ] ) ) T( std::forward< Args >( args ) ... );
return data_[ size_ ++ ];
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >& T_Array< T >::addAll(
T_Array< T > const& other ) noexcept
{
if ( other.size_ ) {
ensureCapacity( size_ + other.size_ );
T_ArrayHelpers< T >::copyNew(
other.data_ , &data_[ size_ ] , other.size_ );
size_ += other.size_;
}
return *this;
}
template< typename T >
inline T_Array< T >& T_Array< T >::addAll(
T_Array< T >&& other ) noexcept
{
if ( other.size_ ) {
ensureCapacity( size_ + other.size_ );
T_ArrayHelpers< T >::moveNew(
other.data_ , &data_[ size_ ] , other.size_ );
size_ += other.size_;
other.size_ = 0;
}
return *this;
}
template< typename T >
inline T_Array< T >& T_Array< T >::addAll(
std::initializer_list< T > other ) noexcept
{
ensureCapacity( size_ + other.size( ) );
auto i = size_;
for ( T const& v : other ) {
::new ( ( char* ) &( data_[ i ++ ] ) ) T( v );
}
size_ += other.size( );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T >& T_Array< T >::operator<< (
T const& item ) noexcept
{
add( item );
return *this;
}
template< typename T >
inline T_Array< T >& T_Array< T >::operator<< (
T&& item ) noexcept
{
add( std::move( item ) );
return *this;
}
template< typename T >
inline T_Array< T >& T_Array< T >::operator<< (
T_Array< T > const& other ) noexcept
{
addAll( other );
return *this;
}
template< typename T >
inline T_Array< T >& T_Array< T >::operator<< (
T_Array< T >&& other ) noexcept
{
addAll( std::move( other ) );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_Array< T >::insert(
const uint32_t index ,
T const& item ) noexcept
{
if ( std::is_class< T >( ) ) {
using std::swap;
const auto last( add( item ) );
for ( uint32_t i = index ; i < last ; i ++ ) {
swap( data_[ i ] , data_[ last ] );
}
} else {
ensureCapacity( size_ + 1 );
if ( index < size_ ) {
T_ArrayHelpers< T >::moveAssign( &data_[ index ] ,
&data_[ index + 1 ] , size_ - index );
}
data_[ index ] = item;
size_ ++;
}
}
template< typename T >
inline void T_Array< T >::insert(
const uint32_t index ,
T&& item ) noexcept
{
if ( std::is_class< T >( ) ) {
using std::swap;
const auto last( add( std::move( item ) ) );
for ( uint32_t i = index ; i < last ; i ++ ) {
swap( data_[ i ] , data_[ last ] );
}
} else {
insert( index , (T const&) item );
}
}
template< typename T >
template< typename... Args >
inline T& T_Array< T >::insertNew(
const uint32_t index ,
Args&& ... args )
{
using std::swap;
addNew( std::forward< Args >( args ) ... );
const auto last( size_ - 1 );
for ( uint32_t i = index ; i < last ; i ++ ) {
swap( data_[ i ] , data_[ last ] );
}
return data_[ index ];
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_Array< T >::remove(
const uint32_t index ) noexcept
{
assert( index < size_ );
if ( index != size_ - 1 ) {
T_ArrayHelpers< T >::moveAssign( &data_[ index + 1 ] ,
&data_[ index ] , size_ - ( index + 1 ) );
}
data_[ size_ - 1 ].~T( );
size_ --;
}
template< typename T >
inline void T_Array< T >::removeSwap(
const uint32_t index ) noexcept
{
assert( index < size_ );
if ( index != size_ - 1 ) {
data_[ index ] = std::move( data_[ size_ - 1 ] );
}
data_[ size_ - 1 ].~T( );
size_ --;
}
template< typename T >
inline void T_Array< T >::removeLast( ) noexcept
{
assert( size_ );
data_[ size_ - 1 ].~T( );
size_ --;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_Array< T >::sort(
F_Comparator< T > cmp ) noexcept
{
sort( 0 , size_ , std::move( cmp ) );
}
template< typename T >
inline void T_Array< T >::sort(
const uint32_t first ,
const uint32_t items ,
F_Comparator< T > cmp ) noexcept
{
if ( items != 0 ) {
assert( first < size_ );
assert( first + items <= size_ );
Sort( &data_[ first ] , items , std::move( cmp ) );
}
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Array< T > T_Array< T >::copyRange(
const uint32_t first ,
const uint32_t last ) const noexcept
{
if ( first >= size_ || last < first ) {
return T_Array< T >( 1 );
}
const auto l( std::min( last , size_ - 1 ) );
T_Array< T > output( growth_ );
output.ensureCapacity( l - first + 1 );
output.size_ = l - first + 1;
T_ArrayHelpers< T >::copyNew( &data_[ first ] , output.data_ , output.size_ );
return output;
}
template< typename T >
inline T_Array< T > T_Array< T >::moveRange(
const uint32_t first ,
const uint32_t last ) noexcept
{
if ( first >= size_ || last < first ) {
return T_Array< T >( 1 );
}
const auto l( std::min( last , size_ - 1 ) );
T_Array< T > output( growth_ );
output.ensureCapacity( l - first + 1 );
output.size_ = l - first + 1;
T_ArrayHelpers< T >::moveNew( &data_[ first ] , output.data_ , output.size_ );
return output;
}
/*----------------------------------------------------------------------------*/
#define M_TMPL_ typename T
#define M_TGT_ T_Array< T >
#include "ebcl/bits/ArrayIteratorMethods.hh"
/*= T_Array::T_Iterator_ =====================================================*/
#define M_TMPL_ typename T
#define M_TGT_ T_Array< T >
#include "ebcl/bits/ArrayIterator.hh"
/*= T_Array::T_ConstIterator_ ================================================*/
#define M_TMPL_ typename T
#define M_TGT_ T_Array< T >
#include "ebcl/bits/ArrayConstIterator.hh"
/*= T_StaticArray ============================================================*/
template< typename T , uint32_t S >
inline T_StaticArray< T , S >::T_StaticArray( ) noexcept
: size_( 0 )
{ }
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline T_StaticArray< T , S >::T_StaticArray(
T_Self const& source ) noexcept
: size_( source.size_ )
{
T_ArrayHelpers< T >::copyNew(
reinterpret_cast< T const* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
}
template< typename T , uint32_t S >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator= (
T_Self const& source ) noexcept
{
clear( );
size_ = source.size_;
T_ArrayHelpers< T >::copyNew(
reinterpret_cast< T const* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline T_StaticArray< T , S >::T_StaticArray(
T_Self&& source ) noexcept
: size_( source.size_ )
{
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 >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator= (
T_Self&& source ) noexcept
{
clear( );
size_ = source.size_;
T_ArrayHelpers< T >::move(
reinterpret_cast< T* >( &source.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ 0 ] ) ,
size_ );
source.size_ = 0;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline T_StaticArray< T , S >::~T_StaticArray( ) noexcept
{
clear( );
}
template< typename T , uint32_t S >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::clear( ) noexcept
{
for ( auto i = 0u ; i < size_ ; i ++ ) {
reinterpret_cast< T* >( &storage_[ i ] )->T::~T( );
}
size_ = 0;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
void swap(
T_StaticArray< T , S >& lhs ,
T_StaticArray< T , S >& rhs ) noexcept
{
using T_ = T_StaticArray< T , S >;
if ( lhs.size( ) && rhs.size( ) ) {
T_ temp( std::move( rhs ) );
rhs = std::move( lhs );
lhs = std::move( temp );
} else if ( lhs.size( ) || rhs.size( ) ) {
T_& empty( lhs.size( ) ? rhs : lhs );
T_& notEmpty( lhs.size( ) ? lhs : rhs );
empty = std::move( notEmpty );
}
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline constexpr uint32_t T_StaticArray< T , S >::capacity( ) const noexcept
{
return S;
}
template< typename T , uint32_t S >
inline uint32_t T_StaticArray< T , S >::size( ) const noexcept
{
return size_;
}
template< typename T , uint32_t S >
inline bool T_StaticArray< T , S >::empty( ) const noexcept
{
return size_ == 0;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline T& T_StaticArray< T , S >::operator[] (
const uint32_t index ) noexcept
{
assert( index < size_ );
return *reinterpret_cast< T* >( &storage_[ index ] );
}
template< typename T , uint32_t S >
inline T const& T_StaticArray< T , S >::operator[] (
const uint32_t index ) const noexcept
{
assert( index < size_ && size_ <= S );
return *reinterpret_cast< T const* >( &storage_[ index ] );
}
template< typename T , uint32_t S >
inline T& T_StaticArray< T , S >::last( ) noexcept
{
assert( !empty( ) );
return *reinterpret_cast< T* >( &storage_[ size_ - 1 ] );
}
template< typename T , uint32_t S >
inline T const& T_StaticArray< T , S >::last( ) const noexcept
{
assert( !empty( ) );
return *reinterpret_cast< T const* >( &storage_[ size_ - 1 ] );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline int32_t T_StaticArray< T , S >::indexOf(
T const& item ) const noexcept
{
for ( auto i = 0u ; i < size_ ; i ++ ) {
if ( (*this)[ i ] == item ) {
return i;
}
}
return -1;
}
template< typename T , uint32_t S >
inline bool T_StaticArray< T , S >::contains(
T const& item ) const noexcept
{
return indexOf( item ) != -1;
}
template< typename T , uint32_t S >
inline int32_t T_StaticArray< T , S >::indexOf(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( (*this)[ i ] ) ) {
return i;
}
}
return -1;
}
template< typename T , uint32_t S >
inline bool T_StaticArray< T , S >::contains(
std::function< bool( T const& ) > pred ) const noexcept
{
for ( uint32_t i = 0 ; i < size_ ; i ++ ) {
if ( pred( (*this)[ i ] ) ) {
return true;
}
}
return false;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline uint32_t T_StaticArray< T , S >::add(
T&& item ) noexcept
{
assert( size_ < S );
const auto index( size_ ++ );
::new ( (char*) &storage_[ index ] ) T( std::move( item ) );
return index;
}
template< typename T , uint32_t S >
inline uint32_t T_StaticArray< T , S >::add(
T const& item ) noexcept
{
assert( size_ < S );
const auto index( size_ ++ );
::new ( (char*) &storage_[ index ] ) T( item );
return index;
}
template< typename T , uint32_t S >
template< typename... Args >
inline T& T_StaticArray< T , S >::addNew(
Args&& ... args )
{
assert( size_ < S );
const auto index( size_ ++ );
::new ( (char*) &storage_[ index ] ) T( std::forward< Args >( args ) ... );
return (*this)[ index ];
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
T_StaticArray< T , S >& T_StaticArray< T , S >::addAll(
T_Self const& other ) noexcept
{
assert( size_ + other.size_ <= S );
T_ArrayHelpers< T >::copyNew(
reinterpret_cast< T const* >( &other.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ size_ ] ) ,
other.size_ );
size_ += other.size_;
return *this;
}
template< typename T , uint32_t S >
T_StaticArray< T , S >& T_StaticArray< T , S >::addAll(
T_Self&& other ) noexcept
{
assert( size_ + other.size_ <= S );
T_ArrayHelpers< T >::move(
reinterpret_cast< T* >( &other.storage_[ 0 ] ) ,
reinterpret_cast< T* >( &storage_[ size_ ] ) ,
other.size_ );
size_ += other.size_;
other.size_ = 0;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator<< (
T const& item ) noexcept
{
add( item );
return *this;
}
template< typename T , uint32_t S >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator<< (
T&& item ) noexcept
{
add( std::move( item ) );
return *this;
}
template< typename T , uint32_t S >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator<< (
T_Self const& other ) noexcept
{
addAll( other );
return *this;
}
template< typename T , uint32_t S >
inline T_StaticArray< T , S >& T_StaticArray< T , S >::operator<< (
T_Self&& other ) noexcept
{
addAll( std::move( other ) );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::insert(
const uint32_t index ,
T&& item ) noexcept
{
assert( size_ < S );
if ( std::is_class< T >( ) ) {
const auto last( add( std::move( item ) ) );
for ( uint32_t i = index ; i < last ; i ++ ) {
using std::swap;
swap( (*this)[ i ] , (*this)[ last ] );
}
} else {
insert( index , (T const&) item );
}
}
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::insert(
const uint32_t index ,
T const& item ) noexcept
{
assert( size_ < S );
if ( std::is_class< T >( ) ) {
const auto last( add( item ) );
for ( uint32_t i = index ; i < last ; i ++ ) {
using std::swap;
swap( (*this)[ i ] , (*this)[ last ] );
}
} else {
if ( index < size_ ) {
memmove( &storage_[ index + 1 ] , &storage_[ index ] ,
sizeof( T_Storage_ ) * ( size_ - index ) );
}
*reinterpret_cast< T* >( &storage_[ index ] ) = item;
size_ ++;
}
}
template< typename T , uint32_t S >
template< typename... Args >
inline T& T_StaticArray< T , S >::insertNew(
const uint32_t index ,
Args&& ... args )
{
addNew( std::forward< Args >( args ) ... );
const auto last( size_ - 1 );
for ( uint32_t i = index ; i < last ; i ++ ) {
swap( (*this)[ i ] , (*this)[ last ] );
}
return (*this)[ index ];
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::remove(
const uint32_t index ) noexcept
{
assert( index < size_ && size_ <= S );
if ( index != size_ - 1 ) {
T_ArrayHelpers< T >::moveAssign(
reinterpret_cast< T* >( &storage_[ index + 1 ] ) ,
reinterpret_cast< T* >( &storage_[ index ] ) ,
size_ - ( index + 1 ) );
}
removeLast( );
}
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::removeSwap(
const uint32_t index ) noexcept
{
assert( index < size_ && size_ <= S );
if ( index != size_ - 1 ) {
(*this)[ index ] = std::move( (*this)[ size_ - 1 ] );
}
removeLast( );
}
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::removeLast( ) noexcept
{
assert( size_ && size_ <= S );
(*this)[ size_ - 1 ].~T( );
size_ --;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::sort(
const F_Comparator< T > cmp ) noexcept
{
sort( 0 , size_ , cmp );
}
template< typename T , uint32_t S >
inline void T_StaticArray< T , S >::sort(
const uint32_t first ,
const uint32_t items ,
const F_Comparator< T > cmp ) noexcept
{
if ( items != 0 ) {
assert( first < size_ );
assert( first + items <= size_ );
Sort( &(*this)[ first ] , items , cmp );
}
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S >
inline T_StaticArray< T , S > T_StaticArray< T , S >::copyRange(
const uint32_t first ,
const uint32_t last ) const noexcept
{
if ( first >= size_ || last < first ) {
return T_StaticArray< T , S >( );
}
const auto l( std::min( last , size_ - 1 ) );
T_StaticArray< T , S > output;
output.size_ = l - first + 1;
T_ArrayHelpers< T >::copyNew( &(*this)[ first ] , &output[ 0 ] ,
output.size_ );
return output;
}
template< typename T , uint32_t S >
inline T_StaticArray< T , S > T_StaticArray< T , S >::moveRange(
const uint32_t first ,
const uint32_t last ) noexcept
{
if ( first >= size_ || last < first ) {
return T_StaticArray< T , S >( );
}
const auto l( std::min( last , size_ - 1 ) );
T_StaticArray< T , S > output;
for ( uint32_t i = first ; i <= l ; i ++ ) {
output.add( std::move( (*this)[ i ] ) );
}
return output;
}
/*----------------------------------------------------------------------------*/
#define M_TMPL_ typename T , uint32_t SZ
#define M_TGT_ T_StaticArray< T , SZ >
#include "ebcl/bits/ArrayIteratorMethods.hh"
/*= T_StaticArray::T_Iterator_ ===============================================*/
#define M_TMPL_ typename T , uint32_t SZ
#define M_TGT_ T_StaticArray< T , SZ >
#include "ebcl/bits/ArrayIterator.hh"
/*= T_StaticArray::T_ConstIterator_ ==========================================*/
#define M_TMPL_ typename T , uint32_t SZ
#define M_TGT_ T_StaticArray< T , SZ >
#include "ebcl/bits/ArrayConstIterator.hh"
/*= T_AutoArray ==============================================================*/
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >::T_AutoArray( ) noexcept
: array_( )
{ }
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >::T_AutoArray(
T_Self const& source ) noexcept
: array_( source.array_ )
{ }
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::operator =(
T_Self const& source ) noexcept
{
array_ = source.array_;
return *this;
}
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >::T_AutoArray(
T_Self&& source ) noexcept
: array_( std::move( source.array_ ) )
{ }
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::operator =(
T_Self&& source ) noexcept
{
array_ = std::move( source.array_ );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline void swap(
T_AutoArray< T , S , G >& lhs ,
T_AutoArray< T , S , G >& rhs ) noexcept
{
swap( lhs.array_ , rhs.array_ );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::clear( ) noexcept
{
if ( isStatic( ) ) {
static_( ).clear( );
} else {
dynamic_( ).clear( );
}
return *this;
}
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::free( ) noexcept
{
array_ = T_Static_( );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline uint32_t T_AutoArray< T , S , G >::capacity( ) const noexcept
{
return isStatic( ) ? S : dynamic_( ).capacity( );
}
template< typename T , uint32_t S , uint32_t G >
inline uint32_t T_AutoArray< T , S , G >::size( ) const noexcept
{
return isStatic( ) ? static_( ).size( ) : dynamic_( ).size( );
}
template< typename T , uint32_t S , uint32_t G >
inline constexpr uint32_t T_AutoArray< T , S , G >::growth( ) const noexcept
{
return G;
}
template< typename T , uint32_t S , uint32_t G >
inline bool T_AutoArray< T , S , G >::isStatic( ) const noexcept
{
return array_.template hasType< T_Static_ >( );
}
template< typename T , uint32_t S , uint32_t G >
inline bool T_AutoArray< T , S , G >::empty( ) const noexcept
{
return size( ) == 0;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::ensureCapacity(
const uint32_t capacity ) noexcept
{
if ( capacity > S ) {
if ( isStatic( ) ) {
convertToDynamic_( capacity );
} else {
dynamic_( ).ensureCapacity( capacity );
}
}
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline T& T_AutoArray< T , S , G >::operator[] (
const uint32_t index ) noexcept
{
return isStatic( ) ? static_( )[ index ] : dynamic_( )[ index ];
}
template< typename T , uint32_t S , uint32_t G >
inline T const& T_AutoArray< T , S , G >::operator[] (
const uint32_t index ) const noexcept
{
return isStatic( ) ? static_( )[ index ] : dynamic_( )[ index ];
}
template< typename T , uint32_t S , uint32_t G >
inline T& T_AutoArray< T , S , G >::last( ) noexcept
{
assert( !empty( ) );
return (*this)[ size( ) - 1 ];
}
template< typename T , uint32_t S , uint32_t G >
inline T const& T_AutoArray< T , S , G >::last( ) const noexcept
{
assert( !empty( ) );
return (*this)[ size( ) - 1 ];
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline int32_t T_AutoArray< T , S , G >::indexOf(
T const& item ) const noexcept
{
return isStatic( )
? static_( ).indexOf( item )
: dynamic_( ).indexOf( item );
}
template< typename T , uint32_t S , uint32_t G >
inline bool T_AutoArray< T , S , G >::contains(
T const& item ) const noexcept
{
return indexOf( item ) != -1;
}
template< typename T , uint32_t S , uint32_t G >
inline int32_t T_AutoArray< T , S , G >::indexOf(
std::function< bool( T const& ) > pred ) const noexcept
{
return isStatic( )
? static_( ).indexOf( std::move( pred ) )
: dynamic_( ).indexOf( std::move( pred ) );
}
template< typename T , uint32_t S , uint32_t G >
inline bool T_AutoArray< T , S , G >::contains(
std::function< bool( T const& ) > pred ) const noexcept
{
return isStatic( )
? static_( ).contains( std::move( pred ) )
: dynamic_( ).contains( std::move( pred ) );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline uint32_t T_AutoArray< T , S , G >::add(
T const& item ) noexcept
{
ensureCapacity( size( ) + 1 );
return isStatic( ) ? static_( ).add( item ) : dynamic_( ).add( item );
}
template< typename T , uint32_t S , uint32_t G >
inline uint32_t T_AutoArray< T , S , G >::add(
T&& item ) noexcept
{
ensureCapacity( size( ) + 1 );
return isStatic( )
? static_( ).add( std::move( item ) )
: dynamic_( ).add( std::move( item ) );
}
template< typename T , uint32_t S , uint32_t G >
template< typename... Args >
inline T& T_AutoArray< T , S , G >::addNew(
Args&& ... args )
{
ensureCapacity( size( ) + 1 );
return isStatic( )
? static_( ).addNew( std::forward< Args >( args ) ... )
: dynamic_( ).addNew( std::forward< Args >( args ) ... );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::addAll(
T_Self const& other ) noexcept
{
const auto osz( other.size( ) );
if ( !osz ) {
return *this;
}
// Try using container's native addAll() if we can
const auto inisz( size( ) );
const bool tst( isStatic( ) );
const bool ost( other.isStatic( ) );
if ( tst == ost && ( !tst || inisz + osz <= S ) ) {
if ( tst ) {
static_( ).addAll( other.static_( ) );
} else {
dynamic_( ).addAll( other.dynamic_( ) );
}
return *this;
}
// Otherwise we need to add manually.
ensureCapacity( inisz + osz );
if ( isStatic( ) ) {
for ( uint32_t i = 0 ; i < osz ; i ++ ) {
static_( ).add( other[ i ] );
}
} else {
for ( uint32_t i = 0 ; i < osz ; i ++ ) {
dynamic_( ).add( other[ i ] );
}
}
return *this;
}
template< typename T , uint32_t S , uint32_t G >
inline T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::addAll(
T_Self&& other ) noexcept
{
const auto osz( other.size( ) );
if ( !osz ) {
return *this;
}
// Try using container's native addAll() if we can
const auto inisz( size( ) );
const bool tst( isStatic( ) );
const bool ost( other.isStatic( ) );
if ( tst == ost && ( !tst || inisz + osz <= S ) ) {
if ( tst ) {
static_( ).addAll( std::move( other.static_( ) ) );
} else {
dynamic_( ).addAll( std::move( other.dynamic_( ) ) );
}
return *this;
}
// Otherwise we need to add manually.
ensureCapacity( inisz + osz );
if ( isStatic( ) ) {
for ( uint32_t i = 0 ; i < osz ; i ++ ) {
static_( ).add( std::move( other[ i ] ) );
}
} else {
for ( uint32_t i = 0 ; i < osz ; i ++ ) {
dynamic_( ).add( std::move( other[ i ] ) );
}
}
other.free( );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline void T_AutoArray< T , S , G >::insert(
const uint32_t index ,
T const& item ) noexcept
{
ensureCapacity( size( ) + 1 );
return isStatic( )
? static_( ).insert( index , item )
: dynamic_( ).insert( index , item );
}
template< typename T , uint32_t S , uint32_t G >
inline void T_AutoArray< T , S , G >::insert(
const uint32_t index ,
T&& item ) noexcept
{
ensureCapacity( size( ) + 1 );
return isStatic( )
? static_( ).insert( index , std::move( item ) )
: dynamic_( ).insert( index , std::move( item ) );
}
template< typename T , uint32_t S , uint32_t G >
template< typename... Args >
inline T& T_AutoArray< T , S , G >::insertNew(
const uint32_t index ,
Args&& ... args )
{
ensureCapacity( size( ) + 1 );
return isStatic( )
? static_( ).insertNew( index , std::forward< Args >( args ) ... )
: dynamic_( ).insertNew( index , std::forward< Args >( args ) ... );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline void T_AutoArray< T , S , G >::remove(
const uint32_t index ) noexcept
{
isStatic( )
? static_( ).remove( index )
: dynamic_( ).remove( index );
}
template< typename T , uint32_t S , uint32_t G >
inline void T_AutoArray< T , S , G >::removeSwap(
const uint32_t index ) noexcept
{
isStatic( )
? static_( ).removeSwap( index )
: dynamic_( ).removeSwap( index );
}
template< typename T , uint32_t S , uint32_t G >
inline void T_AutoArray< T , S , G >::removeLast( ) noexcept
{
assert( !empty( ) );
remove( size( ) - 1 );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
void T_AutoArray< T , S , G >::sort(
F_Comparator< T > cmp ) noexcept
{
sort( 0 , size( ) , std::move( cmp ) );
}
template< typename T , uint32_t S , uint32_t G >
void T_AutoArray< T , S , G >::sort(
const uint32_t first ,
const uint32_t items ,
F_Comparator< T > cmp ) noexcept
{
if ( isStatic( ) ) {
static_( ).sort( first , items , std::move( cmp ) );
} else {
dynamic_( ).sort( first , items , std::move( cmp ) );
}
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
T_AutoArray< T , S , G > T_AutoArray< T , S , G >::copyRange(
const uint32_t first ,
const uint32_t last ) const noexcept
{
// XXX: this uses manual calls to underlying add() methods; it could
// be optimised, but I'm not sure it's necessary to do so.
auto const sz( size( ) );
if ( first >= sz || last < first ) {
return T_Self( );
}
const auto l( std::min( last , sz - 1 ) );
T_Self nd;
nd.ensureCapacity( l - first + 1 );
if ( isStatic( ) ) {
T_Static_ const& src( static_( ) );
T_Static_& dst( nd.static_( ) );
for ( auto i = first ; i <= l ; i ++ ) {
dst.add( src[ i ] );
}
} else if ( nd.isStatic( ) ) {
T_Dynamic_ const& src( dynamic_( ) );
T_Static_& dst( nd.static_( ) );
for ( auto i = first ; i <= l ; i ++ ) {
dst.add( src[ i ] );
}
} else {
T_Dynamic_ const& src( dynamic_( ) );
T_Dynamic_& dst( nd.dynamic_( ) );
for ( auto i = first ; i <= l ; i ++ ) {
dst.add( src[ i ] );
}
}
return nd;
}
template< typename T , uint32_t S , uint32_t G >
T_AutoArray< T , S , G > T_AutoArray< T , S , G >::moveRange(
const uint32_t first ,
const uint32_t last ) noexcept
{
// XXX: this uses manual calls to underlying add() methods; it could
// be optimised, but I'm not sure it's necessary to do so.
auto const sz( size( ) );
if ( first >= sz || last < first ) {
return T_Self( );
}
const auto l( std::min( last , sz - 1 ) );
T_Self nd;
nd.ensureCapacity( l - first + 1 );
if ( isStatic( ) ) {
T_Static_& src( static_( ) );
T_Static_& dst( nd.static_( ) );
for ( auto i = first ; i <= l ; i ++ ) {
dst.add( std::move( src[ i ] ) );
}
} else if ( nd.isStatic( ) ) {
T_Dynamic_& src( dynamic_( ) );
T_Static_& dst( nd.static_( ) );
for ( auto i = first ; i <= l ; i ++ ) {
dst.add( std::move( src[ i ] ) );
}
} else {
T_Dynamic_& src( dynamic_( ) );
T_Dynamic_& dst( nd.dynamic_( ) );
for ( auto i = first ; i <= l ; i ++ ) {
dst.add( std::move( src[ i ] ) );
}
}
return nd;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
void T_AutoArray< T , S , G >::convertToDynamic_(
const uint32_t capacity ) noexcept
{
assert( isStatic( ) );
T_Static_& s( static_( ) );
T_Dynamic_ d( G );
d.ensureCapacity( std::max( s.capacity( ) , capacity ) );
auto const sz( s.size( ) );
for ( auto i = 0u ; i < sz ; i ++ ) {
d.add( std::move( s[ i ] ) );
}
array_ = std::move( d );
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::operator<< (
T const& item ) noexcept
{
add( item );
return *this;
}
template< typename T , uint32_t S , uint32_t G >
T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::operator<< (
T&& item ) noexcept
{
add( std::move( item ) );
return *this;
}
template< typename T , uint32_t S , uint32_t G >
T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::operator<< (
T_Self const& other ) noexcept
{
addAll( other );
return *this;
}
template< typename T , uint32_t S , uint32_t G >
T_AutoArray< T , S , G >& T_AutoArray< T , S , G >::operator<< (
T_Self&& other ) noexcept
{
addAll( std::move( other ) );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T , uint32_t S , uint32_t G >
inline T_StaticArray< T , S >& T_AutoArray< T , S , G >::static_( ) noexcept
{
return array_.template value< T_Static_ >( );
}
template< typename T , uint32_t S , uint32_t G >
inline T_StaticArray< T , S > const& T_AutoArray< T , S , G >::static_( ) const noexcept
{
return array_.template value< T_Static_ >( );
}
template< typename T , uint32_t S , uint32_t G >
inline T_Array< T >& T_AutoArray< T , S , G >::dynamic_( ) noexcept
{
return array_.template value< T_Dynamic_ >( );
}
template< typename T , uint32_t S , uint32_t G >
inline T_Array< T > const& T_AutoArray< T , S , G >::dynamic_( ) const noexcept
{
return array_.template value< T_Dynamic_ >( );
}
/*----------------------------------------------------------------------------*/
#define M_TMPL_ typename T , uint32_t S , uint32_t G
#define M_TGT_ T_AutoArray< T , S , G >
#include "ebcl/bits/ArrayIteratorMethods.hh"
/*= T_StaticArray::T_Iterator_ ===============================================*/
#define M_TMPL_ typename T , uint32_t S , uint32_t G
#define M_TGT_ T_AutoArray< T , S , G >
#include "ebcl/bits/ArrayIterator.hh"
/*= T_StaticArray::T_ConstIterator_ ==========================================*/
#define M_TMPL_ typename T , uint32_t S , uint32_t G
#define M_TGT_ T_AutoArray< T , S , G >
#include "ebcl/bits/ArrayConstIterator.hh"
} // namespace
#endif // _H_EBCL_INLINE_ARRAYS