/******************************************************************************/ /* ARRAYS - INLINE CODE *******************************************************/ /******************************************************************************/ #ifndef _H_EBCL_INLINE_ARRAYS #define _H_EBCL_INLINE_ARRAYS #include 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