/******************************************************************************/ /* SETS ***********************************************************************/ /******************************************************************************/ #ifndef _H_EBCL_SETS #define _H_EBCL_SETS #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 T_Array to be used M_DEFINE_TEMPLATE_TAG( ArrayBacked , uint32_t InPlace , uint32_t Growth = 0 ); //M_DEFINE_TAG( IndexBacked ); 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; bool add( Type const& item ) noexcept; bool add( Type&& item ) noexcept; bool remove( Type const& item ) noexcept; }; 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; bool add( Type const& item ) noexcept; bool add( Type&& item ) noexcept; bool remove( Type const& item ) noexcept; }; struct T_SetHelper { using DefaultImplementation = ArrayBacked< 8 >; // FIXME should use Index by default template< typename Type > using DefaultType = T_SetImplementation< Type , DefaultImplementation >; template< typename Type > static constexpr auto DefaultSize{ sizeof( DefaultType< Type > ) }; template< typename Type > static constexpr auto DefaultAlign{ alignof( DefaultType< Type > ) }; enum E_Operation { INIT , DESTROY , SIZE , INDEX_OF , ADD_COPY , ADD_MOVE , REMOVE , }; template< typename Type , typename Impl > struct T_InPlaceHandler { static void shdl( E_Operation operation , void* wArg , void const* rArg , void* output ); }; template< typename Type , typename Impl > struct T_HeapHandler { static void shdl( E_Operation operation , void* wArg , void const* rArg , void* output ); }; 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 > >; using F_Handler = std::function< void( E_Operation , void* , void const* , void* ) >; }; template< typename Type > class T_Set { private: std::aligned_storage_t< T_SetHelper::DefaultSize< Type > , T_SetHelper::DefaultAlign< Type > > storage_; const T_SetHelper::F_Handler handler_; public: T_Set( ) noexcept; template< typename Tag > T_Set( UseTag< Tag > impl ) noexcept; ~T_Set( ); // --------------------------------------------------------------------- uint32_t size( ) const noexcept; bool contains( Type const& item ) const noexcept; int32_t indexOf( Type const& item ) const noexcept; // --------------------------------------------------------------------- bool add( Type const& item ) noexcept; bool add( Type&& item ) noexcept; bool remove( Type const& item ) noexcept; }; } #endif // _H_EBCL_SETS // XXX #include #include "Sets-inline.hh"