/******************************************************************************/ /* 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" }; /*= 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