575 lines
16 KiB
C++
575 lines
16 KiB
C++
/******************************************************************************/
|
|
/* ARRAYS *********************************************************************/
|
|
/******************************************************************************/
|
|
|
|
#ifndef _H_EBCL_ARRAYS
|
|
#define _H_EBCL_ARRAYS
|
|
#include <ebcl/Externals.hh>
|
|
#include <ebcl/Pointers.hh>
|
|
#include <ebcl/Utilities.hh>
|
|
#include <ebcl/Types.hh>
|
|
namespace ebcl {
|
|
|
|
|
|
// TODO:
|
|
// * add addAll({})
|
|
// * add ={} / cons({})
|
|
|
|
|
|
/*= DYNAMIC ARRAYS ===========================================================*/
|
|
|
|
template< class T >
|
|
class T_Array final
|
|
{
|
|
public:
|
|
static constexpr uint32_t DEFAULT_GROWTH( )
|
|
{
|
|
return std::max< uint32_t >( 1 , 4096 / sizeof( T ) );
|
|
}
|
|
|
|
template< ptrdiff_t Direction >
|
|
class T_Iterator_ final : public std::iterator<
|
|
std::random_access_iterator_tag , T >
|
|
{
|
|
private:
|
|
T_Array< T >* array_;
|
|
ptrdiff_t pos_;
|
|
|
|
public:
|
|
T_Iterator_( T_Array< T >& array ,
|
|
const ptrdiff_t pos ) noexcept;
|
|
|
|
M_ITER_CONS_DEF( T_Iterator_ );
|
|
M_ITER_CONS_COPY( T_Iterator_ );
|
|
M_ITER_SWAP( T_Iterator_ , T_Array );
|
|
M_ITER_CMP_ALL( T_Iterator_ );
|
|
M_ITER_DEREF_RANDOM( T& , T* );
|
|
M_ITER_OPS_RANDOM( T_Iterator_ );
|
|
|
|
bool valid( ) const noexcept;
|
|
T_Array< T >* target( ) const noexcept;
|
|
ptrdiff_t pos( ) const noexcept;
|
|
};
|
|
using T_Iterator = T_Iterator_< 1 >;
|
|
using T_ReverseIterator = T_Iterator_< -1 >;
|
|
|
|
template< ptrdiff_t Direction >
|
|
class T_ConstIterator_ : public std::iterator<
|
|
std::random_access_iterator_tag , T >
|
|
{
|
|
private:
|
|
T_Array< T > const* array_;
|
|
ptrdiff_t pos_;
|
|
|
|
public:
|
|
T_ConstIterator_( T_Array< T > const& array ,
|
|
const ptrdiff_t pos ) noexcept;
|
|
|
|
T_ConstIterator_( typename T_Array< T >::T_Iterator const& iterator ) noexcept;
|
|
T_ConstIterator_& operator =(
|
|
typename T_Array< T >::T_Iterator const& iterator ) noexcept;
|
|
|
|
M_ITER_CONS_DEF( T_ConstIterator_ );
|
|
M_ITER_CONS_COPY( T_ConstIterator_ );
|
|
M_ITER_SWAP( T_ConstIterator_ , T_Array );
|
|
M_ITER_CMP_ALL( T_ConstIterator_ );
|
|
M_ITER_DEREF_RANDOM( T const& , T const* );
|
|
M_ITER_OPS_RANDOM( T_ConstIterator_ );
|
|
|
|
bool valid( ) const noexcept;
|
|
T_Array< T >* target( ) const noexcept;
|
|
ptrdiff_t pos( ) const noexcept;
|
|
};
|
|
using T_ConstIterator = T_ConstIterator_< 1 >;
|
|
using T_ConstReverseIterator = T_ConstIterator_< -1 >;
|
|
|
|
private:
|
|
typedef T_Array< T > MyType_;
|
|
|
|
T* data_;
|
|
uint32_t capacity_;
|
|
uint32_t size_;
|
|
uint32_t growth_;
|
|
|
|
public:
|
|
M_TEMPLATE_POINTERS( MyType_ );
|
|
|
|
T_Array( ) noexcept;
|
|
explicit T_Array( uint32_t growth ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Array( MyType_ const& source ) noexcept;
|
|
MyType_& operator= ( MyType_ const& other ) noexcept;
|
|
|
|
T_Array( MyType_&& source ) noexcept;
|
|
MyType_& operator= ( MyType_&& other ) noexcept;
|
|
|
|
T_Array( std::initializer_list< T > list ) noexcept;
|
|
MyType_& operator= ( std::initializer_list< T > list ) noexcept;
|
|
|
|
template< typename TP >
|
|
friend void swap( T_Array< TP >& lhs ,
|
|
T_Array< TP >& rhs ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
~T_Array( );
|
|
|
|
MyType_& clear( ) noexcept;
|
|
MyType_& free( ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t capacity( ) const noexcept;
|
|
uint32_t size( ) const noexcept;
|
|
uint32_t growth( ) const noexcept;
|
|
bool empty( ) const noexcept;
|
|
|
|
MyType_& ensureCapacity( uint32_t capacity ) noexcept;
|
|
|
|
template<
|
|
typename Q = T ,
|
|
typename = std::enable_if_t< std::is_default_constructible< Q >::value >
|
|
> MyType_& resize( const uint32_t size );
|
|
|
|
template<
|
|
typename Q = T ,
|
|
typename = std::enable_if_t< std::is_copy_constructible< Q >::value >
|
|
> MyType_& resize( const uint32_t size ,
|
|
T const& value );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T& operator[] ( uint32_t index ) noexcept;
|
|
T const& operator[] ( uint32_t index ) const noexcept;
|
|
|
|
T& last( ) noexcept;
|
|
T const& last( ) const noexcept;
|
|
|
|
// Find items (requires comparison operator)
|
|
int32_t indexOf( T const& item ) const noexcept;
|
|
bool contains( T const& item ) const noexcept;
|
|
|
|
// Find items based on a predicate
|
|
int32_t indexOf( std::function< bool( T const& ) > pred ) const noexcept;
|
|
bool contains( std::function< bool( T const& ) > pred ) const noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t add( T const& item ) noexcept;
|
|
uint32_t add( T&& item ) noexcept;
|
|
|
|
template< typename... Args >
|
|
T& addNew( Args&& ... args );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
MyType_& addAll( MyType_ const& other ) noexcept;
|
|
MyType_& addAll( MyType_&& other ) noexcept;
|
|
MyType_& addAll( std::initializer_list< T > values ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
MyType_& operator<< ( T const& item ) noexcept;
|
|
MyType_& operator<< ( T&& item ) noexcept;
|
|
MyType_& operator<< ( MyType_ const& other ) noexcept;
|
|
MyType_& operator<< ( MyType_&& other ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void insert( uint32_t index ,
|
|
T const& item ) noexcept;
|
|
void insert( uint32_t index ,
|
|
T&& item ) noexcept;
|
|
|
|
template< typename... Args >
|
|
T& insertNew( uint32_t index ,
|
|
Args&& ... args );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void remove( uint32_t index ) noexcept;
|
|
void removeSwap( uint32_t index ) noexcept;
|
|
void removeLast( ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sort( F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
|
|
void sort( uint32_t first ,
|
|
uint32_t items ,
|
|
F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
MyType_ copyRange( uint32_t first ,
|
|
uint32_t last = UINT32_MAX ) const noexcept;
|
|
|
|
MyType_ moveRange( uint32_t first ,
|
|
uint32_t last = UINT32_MAX ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Iterators for C++ for loops
|
|
|
|
T_ConstIterator begin( ) const noexcept;
|
|
T_ConstIterator end( ) const noexcept;
|
|
|
|
T_ConstReverseIterator rbegin( ) const noexcept;
|
|
T_ConstReverseIterator rend( ) const noexcept;
|
|
|
|
T_ConstIterator cbegin( ) const noexcept;
|
|
T_ConstIterator cend( ) const noexcept;
|
|
|
|
T_ConstReverseIterator crbegin( ) const noexcept;
|
|
T_ConstReverseIterator crend( ) const noexcept;
|
|
|
|
T_Iterator begin( ) noexcept;
|
|
T_Iterator end( ) noexcept;
|
|
|
|
T_ReverseIterator rbegin( ) noexcept;
|
|
T_ReverseIterator rend( ) noexcept;
|
|
};
|
|
|
|
// Instantiate some common types directly
|
|
extern template class T_Array< uint32_t >;
|
|
|
|
|
|
/*= STATICALLY ALLOCATED ARRAYS ==============================================*/
|
|
/* These arrays offer the same interface as dynamic arrays, but are in fact
|
|
* implemented as in-place storage.
|
|
*/
|
|
|
|
template< typename Type , uint32_t Size >
|
|
class T_StaticArray final
|
|
{
|
|
static_assert( Size > 0 , "Size must be greater than 0" );
|
|
|
|
public:
|
|
using T_Self = T_StaticArray< Type , Size >;
|
|
|
|
private:
|
|
// Actual storage type
|
|
using T_Storage_ = std::aligned_storage_t<
|
|
sizeof( Type ) , alignof( Type )
|
|
>;
|
|
|
|
T_Storage_ storage_[ Size ];
|
|
uint32_t size_;
|
|
|
|
public:
|
|
M_TEMPLATE_POINTERS( T_Self );
|
|
|
|
T_StaticArray( ) noexcept;
|
|
|
|
// Copy
|
|
T_StaticArray( T_Self const& source ) noexcept;
|
|
T_Self& operator= ( T_Self const& other ) noexcept;
|
|
|
|
// Move
|
|
T_StaticArray( T_Self&& source ) noexcept;
|
|
T_Self& operator= ( T_Self&& other ) noexcept;
|
|
|
|
~T_StaticArray( ) noexcept;
|
|
T_Self& clear( ) noexcept;
|
|
|
|
template< typename T , uint32_t S >
|
|
friend void swap(
|
|
T_StaticArray< T , S >& lhs ,
|
|
T_StaticArray< T , S >& rhs ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
constexpr uint32_t capacity( ) const noexcept;
|
|
uint32_t size( ) const noexcept;
|
|
bool empty( ) const noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
Type& operator[] ( uint32_t index ) noexcept;
|
|
Type const& operator[] ( uint32_t index ) const noexcept;
|
|
|
|
Type& last( ) noexcept;
|
|
Type const& last( ) const noexcept;
|
|
|
|
// Find items (requires comparison operator)
|
|
int32_t indexOf( Type const& item ) const noexcept;
|
|
bool contains( Type const& item ) const noexcept;
|
|
|
|
// Find items based on a predicate
|
|
int32_t indexOf( std::function< bool( Type const& ) > pred ) const noexcept;
|
|
bool contains( std::function< bool( Type const& ) > pred ) const noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t add( Type&& item ) noexcept;
|
|
uint32_t add( Type const& item ) noexcept;
|
|
template< typename... Args >
|
|
Type& addNew( Args&& ... args );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self& addAll( T_Self const& other ) noexcept;
|
|
T_Self& addAll( T_Self&& other ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self& operator<< ( Type const& item ) noexcept;
|
|
T_Self& operator<< ( Type&& item ) noexcept;
|
|
T_Self& operator<< ( T_Self const& other ) noexcept;
|
|
T_Self& operator<< ( T_Self&& other ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void insert( uint32_t index ,
|
|
Type&& item ) noexcept;
|
|
void insert( uint32_t index ,
|
|
Type const& item ) noexcept;
|
|
template< typename... Args >
|
|
Type& insertNew( uint32_t index ,
|
|
Args&& ... args );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void remove( uint32_t index ) noexcept;
|
|
void removeSwap( uint32_t index ) noexcept;
|
|
void removeLast( ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sort( F_Comparator< Type > cmp = T_Comparator< Type >::compare ) noexcept;
|
|
void sort( uint32_t first ,
|
|
uint32_t items ,
|
|
F_Comparator< Type > cmp = T_Comparator< Type >::compare ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self copyRange( uint32_t first ,
|
|
uint32_t last = UINT32_MAX ) const noexcept;
|
|
T_Self moveRange( uint32_t first ,
|
|
uint32_t last = UINT32_MAX ) noexcept;
|
|
};
|
|
|
|
|
|
/*= MULTI-ARRAYS ============================================================-*/
|
|
/*
|
|
* Arrays that allow storing multiple values for one entry. Values must be
|
|
* added in order.
|
|
*/
|
|
|
|
template< typename T >
|
|
class T_MultiArray
|
|
{
|
|
public:
|
|
using T_Data = T_Array< T >;
|
|
|
|
private:
|
|
typedef T_MultiArray< T > MyType_;
|
|
|
|
T_Array< uint32_t > meta_;
|
|
T_Data values_;
|
|
|
|
public:
|
|
M_TEMPLATE_POINTERS( T_MultiArray );
|
|
|
|
template< typename TP >
|
|
friend void swap( T_MultiArray< TP >& lhs , T_MultiArray< TP >& rhs );
|
|
|
|
// Start the next entry
|
|
void next( );
|
|
// Add a value to the current entry
|
|
void add( T value );
|
|
// Add a value, calling its constructor
|
|
template<
|
|
typename Q = T ,
|
|
typename... Args ,
|
|
typename = std::enable_if_t< std::is_class< Q >::value >
|
|
>
|
|
Q& addNew( Args&& ... args );
|
|
// Copy an array's contents into the current entry
|
|
void copyFrom( T_Data const& source );
|
|
|
|
// Returns the amount of entries
|
|
uint32_t size( ) const noexcept;
|
|
// Returns the index of the first value for an entry
|
|
uint32_t firstOf( uint32_t item ) const noexcept;
|
|
// Returns the amount of values for an entry
|
|
uint32_t sizeOf( uint32_t item ) const noexcept;
|
|
// Returns the amount of values across all entries
|
|
uint32_t values( ) const noexcept;
|
|
|
|
// Access a value in an entry
|
|
T const& get( uint32_t item , uint32_t sub ) const;
|
|
T& get( uint32_t item , uint32_t sub );
|
|
|
|
// Access a value using its index
|
|
T const& operator[] ( uint32_t index ) const;
|
|
T& operator[] ( uint32_t index );
|
|
|
|
// Is a value present in an entry?
|
|
bool contains( uint32_t index , T const& value ) const;
|
|
|
|
// Reset storage, don't free memory
|
|
void clear( );
|
|
// Reset storage and free memory
|
|
void free( );
|
|
|
|
// Copy values from an entry into the current entry
|
|
void copyFrom( uint32_t index );
|
|
// Copy another multi-array's entry into the current entry
|
|
void copyFrom( MyType_ const& other , uint32_t index );
|
|
|
|
// Copy values from another entry into the current entry if
|
|
// they are not already present. Duplicate entries in the
|
|
// source array are still copied, though.
|
|
void copyUnique( uint32_t index );
|
|
// Copy another multi-array's entry into the current entry,
|
|
// ignoring values that are already present. Duplicates in
|
|
// the source array are still copied.
|
|
void copyUnique( MyType_ const& other , uint32_t index );
|
|
|
|
// Sort an entry's values
|
|
void sort( uint32_t index , F_Comparator< T > cmp = T_Comparator< T >::compare );
|
|
};
|
|
|
|
|
|
// Instantiate some common types directly
|
|
extern template class T_MultiArray< uint32_t >;
|
|
|
|
|
|
/*= AUTOMATIC ARRAYS =========================================================*/
|
|
/* Arrays that are stored in-place up to some limit, then transform into
|
|
* dynamic arrays if necessary.
|
|
*/
|
|
|
|
template<
|
|
typename T , uint32_t StaticSize ,
|
|
uint32_t DynamicGrowth = StaticSize * 4
|
|
> class T_AutoArray
|
|
{
|
|
public:
|
|
using T_Self = T_AutoArray< T , StaticSize , DynamicGrowth >;
|
|
|
|
private:
|
|
using T_Static_ = T_StaticArray< T , StaticSize >;
|
|
using T_Dynamic_ = T_Array< T >;
|
|
|
|
T_Union< T_Static_ , T_Dynamic_ > array_;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
public:
|
|
M_TEMPLATE_POINTERS( T_Self );
|
|
|
|
T_AutoArray( ) noexcept;
|
|
|
|
T_AutoArray( T_Self const& source ) noexcept;
|
|
T_Self& operator =( T_Self const& source ) noexcept;
|
|
|
|
T_AutoArray( T_Self&& source ) noexcept;
|
|
T_Self& operator =( T_Self&& source ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template< typename TP , uint32_t S , uint32_t G >
|
|
friend void swap(
|
|
T_AutoArray< TP , S , G >& lhs ,
|
|
T_AutoArray< TP , S , G >& rhs ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self& clear( ) noexcept;
|
|
T_Self& free( ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t capacity( ) const noexcept;
|
|
uint32_t size( ) const noexcept;
|
|
constexpr uint32_t growth( ) const noexcept;
|
|
bool isStatic( ) const noexcept;
|
|
bool empty( ) const noexcept;
|
|
|
|
T_Self& ensureCapacity( uint32_t capacity ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T& operator[] ( uint32_t index ) noexcept;
|
|
T const& operator[] ( uint32_t index ) const noexcept;
|
|
|
|
T& last( ) noexcept;
|
|
T const& last( ) const noexcept;
|
|
|
|
// Find items (requires comparison operator)
|
|
int32_t indexOf( T const& item ) const noexcept;
|
|
bool contains( T const& item ) const noexcept;
|
|
|
|
// Find items based on a predicate
|
|
int32_t indexOf( std::function< bool( T const& ) > pred ) const noexcept;
|
|
bool contains( std::function< bool( T const& ) > pred ) const noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t add( T const& item ) noexcept;
|
|
uint32_t add( T&& item ) noexcept;
|
|
|
|
template< typename... Args >
|
|
T& addNew( Args&& ... args );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self& addAll( T_Self const& other ) noexcept;
|
|
T_Self& addAll( T_Self&& other ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self& operator<< ( T const& item ) noexcept;
|
|
T_Self& operator<< ( T&& item ) noexcept;
|
|
T_Self& operator<< ( T_Self const& other ) noexcept;
|
|
T_Self& operator<< ( T_Self&& other ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void insert( uint32_t index ,
|
|
T const& item ) noexcept;
|
|
void insert( uint32_t index ,
|
|
T&& item ) noexcept;
|
|
|
|
template< typename... Args >
|
|
T& insertNew( uint32_t index ,
|
|
Args&& ... args );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void remove( uint32_t index ) noexcept;
|
|
void removeSwap( uint32_t index ) noexcept;
|
|
void removeLast( ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sort( F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
|
|
void sort( uint32_t first ,
|
|
uint32_t items ,
|
|
F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_Self copyRange( uint32_t first ,
|
|
uint32_t last = UINT32_MAX ) const noexcept;
|
|
|
|
T_Self moveRange( uint32_t first ,
|
|
uint32_t last = UINT32_MAX ) noexcept;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
private:
|
|
void convertToDynamic_( uint32_t capacity ) noexcept;
|
|
|
|
T_Static_& static_( ) noexcept;
|
|
T_Static_ const& static_( ) const noexcept;
|
|
T_Dynamic_& dynamic_( ) noexcept;
|
|
T_Dynamic_ const& dynamic_( ) const noexcept;
|
|
};
|
|
|
|
|
|
}
|
|
#endif // _H_EBCL_ARRAYS
|
|
#include <ebcl/inline/Arrays.hh>
|