/******************************************************************************/ /* ARRAYS *********************************************************************/ /******************************************************************************/ #ifndef _H_EBCL_ARRAYS #define _H_EBCL_ARRAYS #include #include #include #include namespace ebcl { // 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; template< typename Q = Type , typename = std::enable_if_t< std::is_default_constructible< Q >::value > > T_Self& resize( const uint32_t size ); template< typename Q = Type , typename = std::enable_if_t< std::is_copy_constructible< Q >::value > > T_Self& resize( const uint32_t size , Type const& value ); // --------------------------------------------------------------------- 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; // --------------------------------------------------------------------- // 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" }; /*= 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