diff --git a/include/ebcl/Arrays.hh b/include/ebcl/Arrays.hh index 8e52b51..7c5bf2f 100644 --- a/include/ebcl/Arrays.hh +++ b/include/ebcl/Arrays.hh @@ -285,92 +285,6 @@ class T_StaticArray final }; -/*= 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. diff --git a/include/ebcl/MultiArrays.hh b/include/ebcl/MultiArrays.hh new file mode 100644 index 0000000..b92fb62 --- /dev/null +++ b/include/ebcl/MultiArrays.hh @@ -0,0 +1,101 @@ +/******************************************************************************/ +/* MULTI-ARRAYS ***************************************************************/ +/******************************************************************************/ + +#ifndef _H_EBCL_MULTIARRAYS +#define _H_EBCL_MULTIARRAYS +#include +#include +namespace ebcl { + + +/*= 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 >; +extern template class T_MultiArray< T_String >; + + +} +#endif // _H_EBCL_MULTIARRAYS +#include diff --git a/include/ebcl/SRDParserConfig.hh b/include/ebcl/SRDParserConfig.hh index 43c3f1b..117e6a9 100644 --- a/include/ebcl/SRDParserConfig.hh +++ b/include/ebcl/SRDParserConfig.hh @@ -4,6 +4,7 @@ #ifndef _H_EBCL_SRDPARSERCONFIG #define _H_EBCL_SRDPARSERCONFIG +#include #include #include namespace ebcl { diff --git a/include/ebcl/Strings.hh b/include/ebcl/Strings.hh index 9160b03..c85d0cd 100644 --- a/include/ebcl/Strings.hh +++ b/include/ebcl/Strings.hh @@ -307,7 +307,6 @@ M_DECLARE_COMPARATOR( T_String ); void swap( T_String& lhs , T_String& rhs ) noexcept; extern template class T_Array< T_String >; -extern template class T_MultiArray< T_String >; /*= STRING ITERATORS =========================================================*/ diff --git a/include/ebcl/inline/Arrays.hh b/include/ebcl/inline/Arrays.hh index f4aaee5..ba0d1c6 100644 --- a/include/ebcl/inline/Arrays.hh +++ b/include/ebcl/inline/Arrays.hh @@ -1015,235 +1015,6 @@ inline T_StaticArray< T , S > T_StaticArray< T , S >::moveRange( #include "ebcl/bits/ArrayConstIterator.hh" -/*= T_MultiArray ============================================================-*/ - -template< typename T > -inline void swap( T_MultiArray< T >& lhs , T_MultiArray< T >& rhs ) -{ - using std::swap; - swap( lhs.meta_ , rhs.meta_ ); - swap( lhs.values_ , rhs.values_ ); -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline void T_MultiArray< T >::next( ) -{ - const auto sz( meta_.size( ) ); - const auto first( ( sz == 0 ) ? 0 : ( meta_[ sz - 2 ] + meta_[ sz - 1 ] ) ); - meta_ << first << 0; -} - -template< typename T > -inline void T_MultiArray< T >::add( T value ) -{ - if ( meta_.size( ) == 0 ) { - meta_ << 0 << 1; - } else { - meta_[ meta_.size( ) - 1 ] ++; - } - values_ << value; -} - -template< typename T > -template< - typename Q , - typename... Args , - typename > -inline Q& T_MultiArray< T >::addNew( Args&& ... args ) -{ - if ( meta_.size( ) == 0 ) { - meta_ << 0 << 1; - } else { - meta_[ meta_.size( ) - 1 ] ++; - } - return values_.addNew( std::forward< Args >( args ) ... ); -} - -template< typename T > -inline void T_MultiArray< T >::copyFrom( T_Array< T > const& source ) -{ - values_.addAll( source ); - if ( meta_.size( ) == 0 ) { - meta_ << 0 << source.size( ); - } else { - meta_[ meta_.size( ) - 1 ] += source.size( ); - } -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline uint32_t T_MultiArray< T >::size( ) const noexcept -{ - return meta_.size( ) >> 1; -} - -template< typename T > -inline uint32_t T_MultiArray< T >::firstOf( uint32_t item ) const noexcept -{ - return meta_[ item * 2 ]; -} - -template< typename T > -inline uint32_t T_MultiArray< T >::sizeOf( uint32_t item ) const noexcept -{ - return meta_[ item * 2 + 1 ]; -} - -template< typename T > -inline uint32_t T_MultiArray< T >::values( ) const noexcept -{ - return values_.size( ); -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline T const& T_MultiArray< T >::get( uint32_t item , uint32_t sub ) const -{ - assert( sub < meta_[ item * 2 + 1 ] ); - return values_[ meta_[ item * 2 ] + sub ]; -} - -template< typename T > -inline T& T_MultiArray< T >::get( uint32_t item , uint32_t sub ) -{ - assert( sub < meta_[ item * 2 + 1 ] ); - return values_[ meta_[ item * 2 ] + sub ]; -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline T const& T_MultiArray< T >::operator[] ( uint32_t index ) const -{ - return values_[ index ]; -} - -template< typename T > -inline T& T_MultiArray< T >::operator[] ( uint32_t index ) -{ - return values_[ index ]; -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline bool T_MultiArray< T >::contains( uint32_t index , T const& value ) const -{ - const auto first( firstOf( index ) ); - const auto end( first + sizeOf( index ) ); - for ( uint32_t i = first ; i < end ; i ++ ) { - if ( values_[ i ] == value ) { - return true; - } - } - return false; -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline void T_MultiArray< T >::clear( ) -{ - meta_.clear( ); - values_.clear( ); -} - -template< typename T > -inline void T_MultiArray< T >::free( ) -{ - meta_.free( ); - values_.free( ); -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline void T_MultiArray< T >::copyFrom( uint32_t index ) -{ - copyFrom( *this , index ); -} - -template< typename T > -inline void T_MultiArray< T >::copyFrom( - T_MultiArray< T > const& other , uint32_t index ) -{ - const auto size( other.sizeOf( index ) ); - if ( size == 0 ) { - return; - } - - const auto first( other.firstOf( index ) ); - T const* ptr( &( other[ first ] ) ); - for ( uint32_t i = 0 ; i < size ; i ++ , ptr ++ ) { - values_ << *ptr; - } - if ( meta_.size( ) == 0 ) { - meta_ << 0 << size; - } else { - meta_[ meta_.size( ) - 1 ] += size; - } -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline void T_MultiArray< T >::copyUnique( uint32_t index ) -{ - copyUnique( *this , index ); -} - -template< typename T > -inline void T_MultiArray< T >::copyUnique( T_MultiArray< T > const& other , uint32_t index ) -{ - const auto oSize( other.sizeOf( index ) ); - if ( oSize == 0 ) { - return; - } - - const auto ms( meta_.size( ) ); - const auto tSize( ms == 0 ? 0 : meta_[ ms - 1 ] ); - const auto tFirst( ms == 0 ? 0 : meta_[ ms - 2 ] ); - - const auto oFirst( other.firstOf( index ) ); - T const* ptr( &( other[ oFirst ] ) ); - - uint32_t added = 0; - for ( uint32_t i = 0 ; i < oSize ; i ++ , ptr ++ ) { - bool found = false; - if ( tSize != 0 ) { - T const* pCheck( &values_[ tFirst ] ); - for ( uint32_t j = 0 ; j < tSize ; j ++ , pCheck ++ ) { - if ( *pCheck == *ptr ) { - found = true; - break; - } - } - } - if ( !found ) { - values_ << *ptr; - added ++; - } - } - if ( ms == 0 ) { - meta_ << 0 << added; - } else { - meta_[ ms - 1 ] += added; - } -} - -/*----------------------------------------------------------------------------*/ - -template< typename T > -inline void T_MultiArray< T >::sort( uint32_t index , F_Comparator< T > cmp ) -{ - values_.sort( meta_[ index * 2 ] , meta_[ index * 2 + 1 ] , cmp ); -} - - /*= T_AutoArray ==============================================================*/ template< typename T , uint32_t S , uint32_t G > diff --git a/include/ebcl/inline/MultiArrays.hh b/include/ebcl/inline/MultiArrays.hh new file mode 100644 index 0000000..a95dd02 --- /dev/null +++ b/include/ebcl/inline/MultiArrays.hh @@ -0,0 +1,241 @@ +/******************************************************************************/ +/* ARRAYS - INLINE CODE *******************************************************/ +/******************************************************************************/ + +#ifndef _H_EBCL_INLINE_MULTIARRAYS +#define _H_EBCL_INLINE_MULTIARRAYS +#include +namespace ebcl { + + +/*= T_MultiArray ============================================================-*/ + +template< typename T > +inline void swap( T_MultiArray< T >& lhs , T_MultiArray< T >& rhs ) +{ + using std::swap; + swap( lhs.meta_ , rhs.meta_ ); + swap( lhs.values_ , rhs.values_ ); +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline void T_MultiArray< T >::next( ) +{ + const auto sz( meta_.size( ) ); + const auto first( ( sz == 0 ) ? 0 : ( meta_[ sz - 2 ] + meta_[ sz - 1 ] ) ); + meta_ << first << 0; +} + +template< typename T > +inline void T_MultiArray< T >::add( T value ) +{ + if ( meta_.size( ) == 0 ) { + meta_ << 0 << 1; + } else { + meta_[ meta_.size( ) - 1 ] ++; + } + values_ << value; +} + +template< typename T > +template< + typename Q , + typename... Args , + typename > +inline Q& T_MultiArray< T >::addNew( Args&& ... args ) +{ + if ( meta_.size( ) == 0 ) { + meta_ << 0 << 1; + } else { + meta_[ meta_.size( ) - 1 ] ++; + } + return values_.addNew( std::forward< Args >( args ) ... ); +} + +template< typename T > +inline void T_MultiArray< T >::copyFrom( T_Array< T > const& source ) +{ + values_.addAll( source ); + if ( meta_.size( ) == 0 ) { + meta_ << 0 << source.size( ); + } else { + meta_[ meta_.size( ) - 1 ] += source.size( ); + } +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline uint32_t T_MultiArray< T >::size( ) const noexcept +{ + return meta_.size( ) >> 1; +} + +template< typename T > +inline uint32_t T_MultiArray< T >::firstOf( uint32_t item ) const noexcept +{ + return meta_[ item * 2 ]; +} + +template< typename T > +inline uint32_t T_MultiArray< T >::sizeOf( uint32_t item ) const noexcept +{ + return meta_[ item * 2 + 1 ]; +} + +template< typename T > +inline uint32_t T_MultiArray< T >::values( ) const noexcept +{ + return values_.size( ); +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline T const& T_MultiArray< T >::get( uint32_t item , uint32_t sub ) const +{ + assert( sub < meta_[ item * 2 + 1 ] ); + return values_[ meta_[ item * 2 ] + sub ]; +} + +template< typename T > +inline T& T_MultiArray< T >::get( uint32_t item , uint32_t sub ) +{ + assert( sub < meta_[ item * 2 + 1 ] ); + return values_[ meta_[ item * 2 ] + sub ]; +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline T const& T_MultiArray< T >::operator[] ( uint32_t index ) const +{ + return values_[ index ]; +} + +template< typename T > +inline T& T_MultiArray< T >::operator[] ( uint32_t index ) +{ + return values_[ index ]; +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline bool T_MultiArray< T >::contains( uint32_t index , T const& value ) const +{ + const auto first( firstOf( index ) ); + const auto end( first + sizeOf( index ) ); + for ( uint32_t i = first ; i < end ; i ++ ) { + if ( values_[ i ] == value ) { + return true; + } + } + return false; +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline void T_MultiArray< T >::clear( ) +{ + meta_.clear( ); + values_.clear( ); +} + +template< typename T > +inline void T_MultiArray< T >::free( ) +{ + meta_.free( ); + values_.free( ); +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline void T_MultiArray< T >::copyFrom( uint32_t index ) +{ + copyFrom( *this , index ); +} + +template< typename T > +inline void T_MultiArray< T >::copyFrom( + T_MultiArray< T > const& other , uint32_t index ) +{ + const auto size( other.sizeOf( index ) ); + if ( size == 0 ) { + return; + } + + const auto first( other.firstOf( index ) ); + T const* ptr( &( other[ first ] ) ); + for ( uint32_t i = 0 ; i < size ; i ++ , ptr ++ ) { + values_ << *ptr; + } + if ( meta_.size( ) == 0 ) { + meta_ << 0 << size; + } else { + meta_[ meta_.size( ) - 1 ] += size; + } +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline void T_MultiArray< T >::copyUnique( uint32_t index ) +{ + copyUnique( *this , index ); +} + +template< typename T > +inline void T_MultiArray< T >::copyUnique( T_MultiArray< T > const& other , uint32_t index ) +{ + const auto oSize( other.sizeOf( index ) ); + if ( oSize == 0 ) { + return; + } + + const auto ms( meta_.size( ) ); + const auto tSize( ms == 0 ? 0 : meta_[ ms - 1 ] ); + const auto tFirst( ms == 0 ? 0 : meta_[ ms - 2 ] ); + + const auto oFirst( other.firstOf( index ) ); + T const* ptr( &( other[ oFirst ] ) ); + + uint32_t added = 0; + for ( uint32_t i = 0 ; i < oSize ; i ++ , ptr ++ ) { + bool found = false; + if ( tSize != 0 ) { + T const* pCheck( &values_[ tFirst ] ); + for ( uint32_t j = 0 ; j < tSize ; j ++ , pCheck ++ ) { + if ( *pCheck == *ptr ) { + found = true; + break; + } + } + } + if ( !found ) { + values_ << *ptr; + added ++; + } + } + if ( ms == 0 ) { + meta_ << 0 << added; + } else { + meta_[ ms - 1 ] += added; + } +} + +/*----------------------------------------------------------------------------*/ + +template< typename T > +inline void T_MultiArray< T >::sort( uint32_t index , F_Comparator< T > cmp ) +{ + values_.sort( meta_[ index * 2 ] , meta_[ index * 2 + 1 ] , cmp ); +} + + +} // namespace +#endif // _H_EBCL_INLINE_MULTIARRAYS diff --git a/src/TemplateInstantiation.cc b/src/TemplateInstantiation.cc index 338bdaa..957915a 100644 --- a/src/TemplateInstantiation.cc +++ b/src/TemplateInstantiation.cc @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/tests/arrays-multi.cc b/tests/arrays-multi.cc index 1db4da1..5b6bd8f 100644 --- a/tests/arrays-multi.cc +++ b/tests/arrays-multi.cc @@ -1,4 +1,4 @@ -#include +#include #include using namespace ebcl;