From b0401c5134910c2d1e590d5ce4440ab5d1e32763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Thu, 9 Nov 2017 09:41:28 +0100 Subject: [PATCH] Sets - Now in corelib --- Sets-inline.hh | 638 ------------------------------------------------- Sets.hh | 213 ----------------- ebcl | 2 +- 3 files changed, 1 insertion(+), 852 deletions(-) delete mode 100644 Sets-inline.hh delete mode 100644 Sets.hh diff --git a/Sets-inline.hh b/Sets-inline.hh deleted file mode 100644 index 544196f..0000000 --- a/Sets-inline.hh +++ /dev/null @@ -1,638 +0,0 @@ -/******************************************************************************/ -/* SETS - INLINE CODE *********************************************************/ -/******************************************************************************/ - -#ifndef _H_EBCL_INLINE_SETS -#define _H_EBCL_INLINE_SETS -// XXX #include -#include "Sets.hh" -namespace ebcl { - - -/*= SET IMPLEMENTATION - FULLY DYNAMIC ARRAY =================================*/ - -template< typename Type , uint32_t Growth > -class T_SetImplementation< Type , ArrayBacked< 0 , Growth > > -{ - private: - T_Array< Type > data_; - - public: - template< uint32_t G = Growth , typename std::enable_if_t< G == 0 , int > = 0 - > T_SetImplementation( ) noexcept; - template< uint32_t G = Growth , typename std::enable_if_t< G != 0 , int > = 0 - > T_SetImplementation( ) noexcept; - - uint32_t size( ) const noexcept; - int32_t indexOf( Type const& item ) const noexcept; - Type const* access( uint32_t item ) const noexcept; - - bool add( Type const& item ) noexcept; - bool add( Type&& item ) noexcept; - bool remove( Type const& item ) noexcept; - - void free( ) noexcept; - void clear( ) noexcept; -}; - -/*----------------------------------------------------------------------------*/ - -#define M_TMPL_ template< typename Type , uint32_t Growth > -#define M_TYPE_ T_SetImplementation< Type , ArrayBacked< 0 , Growth > > - -M_TMPL_ -template< uint32_t G , typename std::enable_if_t< G == 0 , int > > -M_TYPE_::T_SetImplementation( ) noexcept - : data_( ) -{ } - -M_TMPL_ -template< uint32_t G , typename std::enable_if_t< G != 0 , int > > -M_TYPE_::T_SetImplementation( ) noexcept - : data_( Growth ) -{ } - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ uint32_t M_TYPE_::size( ) const noexcept -{ - return data_.size( ); -} - -M_TMPL_ int32_t M_TYPE_::indexOf( - Type const& item ) const noexcept -{ - return data_.indexOf( item ); -} - -M_TMPL_ Type const* M_TYPE_::access( - const uint32_t item ) const noexcept -{ - return &data_[ item ]; -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ bool M_TYPE_::add( - Type const& item ) noexcept -{ - const auto ok( indexOf( item ) == -1 ); - if ( ok ) { - data_.add( item ); - } - return ok; -} - -M_TMPL_ bool M_TYPE_::add( - Type&& item ) noexcept -{ - const auto ok( indexOf( item ) == -1 ); - if ( ok ) { - data_.add( std::move( item ) ); - } - return ok; -} - -M_TMPL_ bool M_TYPE_::remove( - Type const& item ) noexcept -{ - const auto index( indexOf( item ) ); - if ( index >= 0 ) { - data_.removeSwap( index ); - } - return index >= 0; -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ void M_TYPE_::free( ) noexcept -{ - data_.free( ); -} - -M_TMPL_ void M_TYPE_::clear( ) noexcept -{ - data_.clear( ); -} - -#undef M_TMPL_ -#undef M_TYPE_ - - -/*= SET IMPLEMENTATION - AUTOMATIC ARRAY =====================================*/ - -template< typename Type , uint32_t InPlace , uint32_t Growth > -class T_SetImplementation< Type , ArrayBacked< InPlace , Growth > > -{ - private: - T_AutoArray< Type , InPlace , - Growth == 0 ? ( InPlace * 4 ) : Growth - > data_; - - public: - uint32_t size( ) const noexcept; - int32_t indexOf( Type const& item ) const noexcept; - Type const* access( uint32_t item ) const noexcept; - - bool add( Type const& item ) noexcept; - bool add( Type&& item ) noexcept; - bool remove( Type const& item ) noexcept; - - void free( ) noexcept; - void clear( ) noexcept; -}; - -/*----------------------------------------------------------------------------*/ - -#define M_TMPL_ template< typename Type , uint32_t ISize , uint32_t Growth > -#define M_TYPE_ T_SetImplementation< Type , ArrayBacked< ISize , Growth > > - -M_TMPL_ uint32_t M_TYPE_::size( ) const noexcept -{ - return data_.size( ); -} - -M_TMPL_ int32_t M_TYPE_::indexOf( - Type const& item ) const noexcept -{ - return data_.indexOf( item ); -} - -M_TMPL_ Type const* M_TYPE_::access( - const uint32_t item ) const noexcept -{ - return &data_[ item ]; -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ bool M_TYPE_::add( - Type const& item ) noexcept -{ - const auto ok( indexOf( item ) == -1 ); - if ( ok ) { - data_.add( item ); - } - return ok; -} - -M_TMPL_ bool M_TYPE_::add( - Type&& item ) noexcept -{ - const auto ok( indexOf( item ) == -1 ); - if ( ok ) { - data_.add( std::move( item ) ); - } - return ok; -} - -M_TMPL_ bool M_TYPE_::remove( - Type const& item ) noexcept -{ - const auto index( indexOf( item ) ); - if ( index >= 0 ) { - data_.removeSwap( index ); - } - return index >= 0; -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ void M_TYPE_::free( ) noexcept -{ - data_.free( ); -} - -M_TMPL_ void M_TYPE_::clear( ) noexcept -{ - data_.clear( ); -} - -#undef M_TMPL_ -#undef M_TYPE_ - - -/*= SET IMPLEMENTATION - INDEX ===============================================*/ - -template< - typename Type , - uint32_t InitialSize , - uint32_t HashSize , - uint32_t Growth -> class T_SetImplementation< Type , IndexBacked< InitialSize , HashSize , Growth > > -{ - static_assert( InitialSize > 0 , "invalid initial size" ); - static_assert( HashSize > 0 , "invalid hash array size" ); - static_assert( Growth > 0 , "invalid growth" ); - - private: - T_HashIndex index_{ HashSize , InitialSize , Growth }; - T_Array< Type > items_{ Growth }; - - public: - uint32_t size( ) const noexcept; - int32_t indexOf( Type const& item ) const noexcept; - Type const* access( uint32_t item ) const noexcept; - - bool add( Type const& item ) noexcept; - bool add( Type&& item ) noexcept; - bool remove( Type const& item ) noexcept; - - void free( ) noexcept; - void clear( ) noexcept; - - private: - uint32_t find( Type const& k , - const uint32_t hash ) const noexcept; -}; - -/*----------------------------------------------------------------------------*/ - -#define M_TMPL_ template< typename Type , uint32_t ISize , uint32_t HSize , uint32_t Growth > -#define M_TYPE_ T_SetImplementation< Type , IndexBacked< ISize , HSize , Growth > > - -M_TMPL_ uint32_t M_TYPE_::size( ) const noexcept -{ - return items_.size( ); -} - -M_TMPL_ int32_t M_TYPE_::indexOf( - Type const& item ) const noexcept -{ - const auto idx{ find( item , ComputeHash( item ) ) }; - return idx == T_HashIndex::INVALID_INDEX ? -1 : int32_t( idx ); -} - -M_TMPL_ Type const* M_TYPE_::access( - const uint32_t item ) const noexcept -{ - return &items_[ item ]; -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ bool M_TYPE_::add( - Type const& item ) noexcept -{ - const auto hash{ ComputeHash( item ) }; - const auto idx{ find( item , hash ) }; - if ( idx == T_HashIndex::INVALID_INDEX ) { - index_.add( hash ); - items_.add( item ); - } - return idx == T_HashIndex::INVALID_INDEX; -} - -M_TMPL_ bool M_TYPE_::add( - Type&& item ) noexcept -{ - const auto hash{ ComputeHash( item ) }; - const auto idx{ find( item , hash ) }; - if ( idx == T_HashIndex::INVALID_INDEX ) { - index_.add( hash ); - items_.add( std::move( item ) ); - } - return idx == T_HashIndex::INVALID_INDEX; -} - -M_TMPL_ bool M_TYPE_::remove( - Type const& item ) noexcept -{ - const auto hash{ ComputeHash( item ) }; - const auto idx{ find( item , hash ) }; - if ( idx != T_HashIndex::INVALID_INDEX ) { - items_.removeSwap( idx ); - index_.remove( idx ); - } - return idx != T_HashIndex::INVALID_INDEX; -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ void M_TYPE_::free( ) noexcept -{ - index_.free( ); - items_.free( ); -} - -M_TMPL_ void M_TYPE_::clear( ) noexcept -{ - index_.clear( ); - items_.clear( ); -} - -/*----------------------------------------------------------------------------*/ - -M_TMPL_ uint32_t M_TYPE_::find( - Type const& k , - const uint32_t hash ) const noexcept -{ - uint32_t idx = index_.first( hash ); - while ( idx != T_HashIndex::INVALID_INDEX ) { - // XXX use a match function? -// if ( match_( keys_[ idx ] , k ) ) { -// break; -// } - if ( items_[ idx ] == k ) { - break; - } - idx = index_.next( idx ); - } - return idx; -} - -#undef M_TMPL_ -#undef M_TYPE_ - - -/*= COMMON HANDLER ===========================================================*/ - -// In-place version -template< typename Type , typename ImplTag > -void T_SetHelper::T_InPlaceHandler< Type , ImplTag >::shdl( - const E_Operation operation , - void* const wArg , - void const* const rArg , - void* const output ) -{ - using T_Impl_ = T_SetImplementation< Type , ImplTag >; - - switch ( operation ) { - - case INIT: - ::new ((char*)output) T_Impl_( ); - break; - - case INIT_COPY: - ::new ((char*)output) T_Impl_( *(T_Impl_ const*)rArg ); - break; - - case INIT_MOVE: - ::new ((char*)output) T_Impl_( std::move( *(T_Impl_*)wArg ) ); - break; - - case DESTROY: - ((T_Impl_*)wArg)->~T_Impl_( ); - break; - - //------------------------------------------------------------------ - - case SIZE: - *((uint32_t*) output) = ((T_Impl_ const*)rArg)->size( ); - break; - - case INDEX_OF: - *((uint32_t*) output) = ((T_Impl_ const*)wArg)->indexOf( - *(Type const*) rArg ); - break; - - case ACCESS: - *((Type const**) output) = ((T_Impl_ const*)rArg)->access( - *(uint32_t const*) wArg ); - break; - - //------------------------------------------------------------------ - - case ADD_COPY: - *((bool*)output) = ((T_Impl_*)wArg)->add( *(Type const*) rArg ); - break; - - case ADD_MOVE: - *((bool*)output) = ((T_Impl_*)wArg)->add( - std::move( *const_cast< Type* >( (Type const*) rArg ) ) ); - break; - - case REMOVE: - *((bool*)output) = ((T_Impl_*)wArg)->remove( *((Type const*) rArg) ); - break; - - //------------------------------------------------------------------ - - case FREE: - ((T_Impl_*)wArg)->free( ); - break; - - case CLEAR: - ((T_Impl_*)wArg)->clear( ); - break; - } -} - -/*----------------------------------------------------------------------------*/ - -// Heap-allocated implementation -template< typename Type , typename ImplTag > -void T_SetHelper::T_HeapHandler< Type , ImplTag >::shdl( - E_Operation operation , - void* wArg , - void const* rArg , - void* output ) -{ - using T_Impl_ = T_SetImplementation< Type , ImplTag >; - - switch ( operation ) { - - case INIT: - *(T_Impl_**)output = ::new T_Impl_( ); - break; - - case INIT_COPY: - *(T_Impl_**)output = ::new T_Impl_( *(T_Impl_ const**)rArg ); - break; - - case INIT_MOVE: - *(T_Impl_**)output = ::new T_Impl_( std::move( *(T_Impl_**)wArg ) ); - break; - - case DESTROY: - delete *(T_Impl_**)wArg; - break; - - //------------------------------------------------------------------ - - case SIZE: - *((uint32_t*) output) = (*(T_Impl_ const**)rArg)->size( ); - break; - - case INDEX_OF: - *((uint32_t*) output) = (*(T_Impl_ const**)wArg)->indexOf( - *(Type const*) rArg ); - break; - - case ACCESS: - *((Type const**) output) = (*(T_Impl_ const**)rArg)->access( - *(uint32_t const*) wArg ); - break; - - //------------------------------------------------------------------ - - case ADD_COPY: - *((bool*)output) = (*(T_Impl_**)wArg)->add( *(Type const*) rArg ); - break; - - case ADD_MOVE: - *((bool*)output) = (*(T_Impl_**)wArg)->add( - std::move( *const_cast< Type* >( (Type const*) rArg ) ) ); - break; - - case REMOVE: - *((bool*)output) = (*(T_Impl_**)wArg)->remove( *((Type const*) rArg) ); - break; - - //------------------------------------------------------------------ - - case FREE: - (*(T_Impl_**)wArg)->free( ); - break; - - case CLEAR: - (*(T_Impl_**)wArg)->clear( ); - break; - } -} - - -/*= T_Set ====================================================================*/ - -template< typename Type > -T_Set< Type >::T_Set( ) noexcept - : T_Set( UseTag< T_SetHelper::DefaultImplementation >( ) ) -{ } - -template< typename Type > -template< typename Tag > -T_Set< Type >::T_Set( const UseTag< Tag > ) noexcept - : handler_( T_SetHelper::T_Handler< Type , Tag >::shdl ) -{ - handler_( T_SetHelper::INIT , nullptr , nullptr , &storage_ ); -} - -/*----------------------------------------------------------------------------*/ - -template< typename Type > -T_Set< Type >::T_Set( - T_Set const& other ) noexcept - : handler_( other.handler_ ) -{ - handler_( T_SetHelper::INIT_COPY , nullptr , &other.storage_ , &storage_ ); -} - -template< typename Type > -T_Set< Type >& T_Set< Type >::operator =( - T_Set const& other ) noexcept -{ - handler_( T_SetHelper::DESTROY , &storage_ , nullptr , nullptr ); - handler_ = other.handler_; - handler_( T_SetHelper::INIT_COPY , nullptr , &other.storage_ , &storage_ ); -} - - -/*----------------------------------------------------------------------------*/ - -template< typename Type > -T_Set< Type >::T_Set( - T_Set&& other ) noexcept - : handler_( other.handler_ ) -{ - handler_( T_SetHelper::INIT_MOVE , &other.storage_ , nullptr , &storage_ ); -} - -template< typename Type > -T_Set< Type >& T_Set< Type >::operator =( - T_Set&& other ) noexcept -{ - handler_( T_SetHelper::DESTROY , &storage_ , nullptr , nullptr ); - handler_ = other.handler_; - handler_( T_SetHelper::INIT_MOVE , &other.storage_ , nullptr , &storage_ ); -} - -/*----------------------------------------------------------------------------*/ - -template< typename Type > -T_Set< Type >::~T_Set( ) -{ - handler_( T_SetHelper::DESTROY , &storage_ , nullptr , nullptr ); -} - -/*----------------------------------------------------------------------------*/ - -template< typename Type > -uint32_t T_Set< Type >::size( ) const noexcept -{ - uint32_t r; - handler_( T_SetHelper::SIZE , nullptr , &storage_ , &r ); - return r; -} - -template< typename Type > -bool T_Set< Type >::contains( - Type const& item ) const noexcept -{ - return indexOf( item ) >= 0; -} - -template< typename Type > -int32_t T_Set< Type >::indexOf( - Type const& item ) const noexcept -{ - int32_t r; - handler_( T_SetHelper::INDEX_OF , const_cast< decltype( storage_ )* >( &storage_ ) , - &item , &r ); - return r; -} - -template< typename Type > -Type const& T_Set< Type >::operator[]( - uint32_t index ) const noexcept -{ - Type* ptr; - handler_( T_SetHelper::ACCESS , &index , &storage_ , &ptr ); - return *ptr; -} - -/*----------------------------------------------------------------------------*/ - -template< typename Type > -bool T_Set< Type >::add( - Type const& item ) noexcept -{ - bool r; - handler_( T_SetHelper::ADD_COPY , &storage_ , &item , &r ); - return r; -} - -template< typename Type > -bool T_Set< Type >::add( - Type&& item ) noexcept -{ - bool r; - handler_( T_SetHelper::ADD_MOVE , &storage_ , &item , &r ); - return r; -} - -template< typename Type > -bool T_Set< Type >::remove( - Type const& item ) noexcept -{ - bool r; - handler_( T_SetHelper::REMOVE , &storage_ , &item , &r ); - return r; -} - -/*----------------------------------------------------------------------------*/ - -template< typename Type > -void T_Set< Type >::free( ) noexcept -{ - handler_( T_SetHelper::FREE , &storage_ , nullptr , nullptr ); -} - -template< typename Type > -void T_Set< Type >::clear( ) noexcept -{ - handler_( T_SetHelper::CLEAR , &storage_ , nullptr , nullptr ); -} - - -} -#endif // _H_EBCL_INLINE_SETS diff --git a/Sets.hh b/Sets.hh deleted file mode 100644 index d15b9ed..0000000 --- a/Sets.hh +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************/ -/* SETS ***********************************************************************/ -/******************************************************************************/ - -#ifndef _H_EBCL_SETS -#define _H_EBCL_SETS -#include -#include -namespace ebcl { - -// FIXME move this to utilities \/ - -// Define a structure that can be used as a tag -#define M_DEFINE_TAG( NAME ) \ - struct NAME { } -// Define a tag structure that can carry arguments -#define M_DEFINE_TEMPLATE_TAG( NAME , ARGS... ) \ - template< ARGS > \ - M_DEFINE_TAG( NAME ) - -// A structure that can be used to carry a tag structure instance -template< typename Tag > -struct UseTag -{ - const Tag tag; - - template< typename ... ArgTypes > - constexpr UseTag( ArgTypes&&... args ) noexcept - : tag( std::forward< ArgTypes >( args ) ... ) { } -}; - - -// Implementation of a set of type Type. The actual implementation is -// determined by the ImplTag type -template< typename Type , typename ImplTag > - class T_SetImplementation; - - -// ArrayBacked implementation tag. InPlace is the amount of items to -// store in-place (0 will cause a fully dynamic array to be used) -M_DEFINE_TEMPLATE_TAG( ArrayBacked , - uint32_t InPlace , - uint32_t Growth = 0 -); - -// IndexBacked implementation tag - the implementation will use a -// T_HashIndex and an array. InitialSize and HashSize affect the index, -// Growth affects both the index and the array. -M_DEFINE_TEMPLATE_TAG( IndexBacked , - uint32_t InitialSize = T_HashIndex::DEFAULT_SIZE , - uint32_t HashSize = T_HashIndex::DEFAULT_SIZE , - uint32_t Growth = T_HashIndex::DEFAULT_GROWTH ); - - -// Templated horrors used by the main T_Set class. -struct T_SetHelper -{ - // Default implementation to use; also determines the in-place - // storage size - using DefaultImplementation = IndexBacked< >; - - // Default implementation class - template< typename Type - > using DefaultType = T_SetImplementation< - Type , DefaultImplementation >; - - // --------------------------------------------------------------------- - - // In-place storage size - template< typename Type - > static constexpr auto DefaultSize{ - sizeof( DefaultType< Type > ) }; - // In-place storage alignment - template< typename Type - > static constexpr auto DefaultAlign{ - alignof( DefaultType< Type > ) }; - - // --------------------------------------------------------------------- - - // Implementation handler operations - enum E_Operation - { - // New instance; output = storage - INIT , - // Copy instance; output = storage, rArg = source - INIT_COPY , - // Move instance; output = storage, wArg = source - INIT_MOVE , - // Destroy instance; wArg = storage - DESTROY , - - // Get size; rArg = storage, output = result - SIZE , - // Get index of element; wArg = storage, rArg = element, output = result - INDEX_OF , - // Access an element; wArg = index , rArg = storage, output = pointer - ACCESS , - - // Add copy of element; wArg = storage, rArg = element, output = result - ADD_COPY , - // Move & add element; wArg = storage, rArg = element, output = result - ADD_MOVE , - // Delete element; wArg = storage, rArg = element, output = result - REMOVE , - - // Free memory; wArg = storage - FREE , - // Clear contents; wArg = storage - CLEAR , - }; - - // Handler function type - using F_Handler = std::function< - void( E_Operation , void* , void const* , void* ) >; - - // --------------------------------------------------------------------- - - // Handler for in-place implementations - template< typename Type , typename Impl - > struct T_InPlaceHandler - { - static void shdl( E_Operation operation , - void* wArg , - void const* rArg , - void* output ); - }; - - // Handler for heap-allocated implementations - template< typename Type , typename Impl - > struct T_HeapHandler - { - static void shdl( E_Operation operation , - void* wArg , - void const* rArg , - void* output ); - }; - - // Use the in-place handler if the implementation data can fit into the - // in-place storage; otherwise use the heap-allocated handler. - template< - typename Type , typename ImplTag , - typename Impl = T_SetImplementation< Type , ImplTag > - > using T_Handler = std::conditional_t< - sizeof( Impl ) <= DefaultSize< Type > , - T_InPlaceHandler< Type , ImplTag > , - T_HeapHandler< Type , ImplTag > - >; -}; - -template< typename Type > -class T_Set -{ - private: - - // Storage area for the implementation's data - std::aligned_storage_t< - T_SetHelper::DefaultSize< Type > , - T_SetHelper::DefaultAlign< Type > - > storage_; - - // Handler - T_SetHelper::F_Handler handler_; - - public: - // Default constructor, using the default implementation - T_Set( ) noexcept; - // Create a set with a specific implementation - template< typename Tag - > T_Set( UseTag< Tag > impl ) noexcept; - - // Copy constructor / assignment - T_Set( T_Set const& other ) noexcept; - T_Set& operator =( T_Set const& other ) noexcept; - - // Move constructor / assignment - T_Set( T_Set&& other ) noexcept; - T_Set& operator =( T_Set&& other ) noexcept; - - ~T_Set( ); - - // --------------------------------------------------------------------- - - // Returns amount of elements - uint32_t size( ) const noexcept; - // Checks if item is in the set - bool contains( Type const& item ) const noexcept; - // Returns underlying index of item, or -1 if not in the set - int32_t indexOf( Type const& item ) const noexcept; - - // Access an element using its underlying index - Type const& operator[]( uint32_t index ) const noexcept; - - // --------------------------------------------------------------------- - - // Add copy of item, returns true if added - bool add( Type const& item ) noexcept; - // Add moved item, returns true if added - bool add( Type&& item ) noexcept; - // Remove item, returns true if removed - bool remove( Type const& item ) noexcept; - - // --------------------------------------------------------------------- - - void clear( ) noexcept; - void free( ) noexcept; -}; - - -} -#endif // _H_EBCL_SETS -// XXX #include -#include "Sets-inline.hh" - diff --git a/ebcl b/ebcl index 0bc11d3..cdbc810 160000 --- a/ebcl +++ b/ebcl @@ -1 +1 @@ -Subproject commit 0bc11d32d746f1075a41137adff51819007d5275 +Subproject commit cdbc81094d266f007b22825d0e5e836804654381