/******************************************************************************/ /* 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 =================================*/ #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_ 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; } #undef M_TMPL_ #undef M_TYPE_ /*= SET IMPLEMENTATION - AUTOMATIC ARRAY =====================================*/ #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_ 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; } #undef M_TMPL_ #undef M_TYPE_ /*= COMMON HANDLER ===========================================================*/ 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*)wArg) T_Impl_( ); 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 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; } } 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_**)wArg = new T_Impl_( ); 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 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; } } /*============================================================================*/ 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 , (char*) &storage_ , nullptr , nullptr ); } 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 > 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; } } #endif // _H_EBCL_INLINE_SETS