corelib/include/ebcl/Arrays.hh

517 lines
15 KiB
C++
Raw Normal View History

/******************************************************************************/
/* 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 {
2017-11-03 11:21:17 +01:00
// TODO:
// * add addAll({})
// * add ={} / cons({})
/*= DYNAMIC ARRAYS ===========================================================*/
template< typename Type >
class T_Array final
{
public:
using T_Self = T_Array< Type >;
static constexpr uint32_t DEFAULT_GROWTH( )
{
return std::max< uint32_t >( 1 , 4096 / sizeof( Type ) );
}
private:
Type* data_;
uint32_t capacity_;
uint32_t size_;
uint32_t growth_;
public:
M_TEMPLATE_POINTERS( T_Self );
T_Array( ) noexcept;
explicit T_Array( uint32_t growth ) noexcept;
// ---------------------------------------------------------------------
T_Array( T_Self const& source ) noexcept;
T_Self& operator= ( T_Self const& other ) noexcept;
T_Array( T_Self&& source ) noexcept;
T_Self& operator= ( T_Self&& other ) noexcept;
T_Array( std::initializer_list< Type > list ) noexcept;
T_Self& operator= ( std::initializer_list< Type > list ) noexcept;
template< typename TP >
friend void swap( T_Array< TP >& lhs ,
T_Array< TP >& rhs ) noexcept;
// ---------------------------------------------------------------------
~T_Array( );
T_Self& clear( ) noexcept;
T_Self& free( ) noexcept;
// ---------------------------------------------------------------------
uint32_t capacity( ) const noexcept;
uint32_t size( ) const noexcept;
uint32_t growth( ) const noexcept;
bool empty( ) const noexcept;
T_Self& ensureCapacity( uint32_t capacity ) noexcept;
2017-11-03 11:21:17 +01:00
template<
typename Q = Type ,
2017-11-03 11:21:17 +01:00
typename = std::enable_if_t< std::is_default_constructible< Q >::value >
> T_Self& resize( const uint32_t size );
2017-11-03 11:21:17 +01:00
template<
typename Q = Type ,
2017-11-03 11:21:17 +01:00
typename = std::enable_if_t< std::is_copy_constructible< Q >::value >
> T_Self& resize( const uint32_t size ,
Type const& value );
2017-11-03 11:21:17 +01:00
// ---------------------------------------------------------------------
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 const& item ) noexcept;
uint32_t add( Type&& 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& addAll( std::initializer_list< Type > values ) 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 const& item ) noexcept;
void insert( uint32_t index ,
Type&& 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;
2017-11-02 14:23:19 +01:00
// ---------------------------------------------------------------------
// C++ iterators
# include "ebcl/bits/ArrayIteratorDecl.hh"
# include "ebcl/bits/ArrayConstIteratorDecl.hh"
# include "ebcl/bits/IteratorMethodsDecl.hh"
};
// 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;
// ---------------------------------------------------------------------
// C++ iterators
# include "ebcl/bits/ArrayIteratorDecl.hh"
# include "ebcl/bits/ArrayConstIteratorDecl.hh"
# include "ebcl/bits/IteratorMethodsDecl.hh"
};
/*= 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 Type , uint32_t StaticSize ,
uint32_t DynamicGrowth = StaticSize * 4
> class T_AutoArray
{
public:
using T_Self = T_AutoArray< Type , StaticSize , DynamicGrowth >;
private:
using T_Static_ = T_StaticArray< Type , StaticSize >;
using T_Dynamic_ = T_Array< Type >;
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;
// ---------------------------------------------------------------------
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 const& item ) noexcept;
uint32_t add( Type&& 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 const& item ) noexcept;
void insert( uint32_t index ,
Type&& 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;
// ---------------------------------------------------------------------
// C++ iterators
# include "ebcl/bits/ArrayIteratorDecl.hh"
# include "ebcl/bits/ArrayConstIteratorDecl.hh"
# include "ebcl/bits/IteratorMethodsDecl.hh"
// ---------------------------------------------------------------------
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>