Sets - Now in corelib
This commit is contained in:
parent
17810a58bf
commit
b0401c5134
3 changed files with 1 additions and 852 deletions
638
Sets-inline.hh
638
Sets-inline.hh
|
@ -1,638 +0,0 @@
|
||||||
/******************************************************************************/
|
|
||||||
/* SETS - INLINE CODE *********************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _H_EBCL_INLINE_SETS
|
|
||||||
#define _H_EBCL_INLINE_SETS
|
|
||||||
// XXX #include <ebcl/Sets.hh>
|
|
||||||
#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
|
|
213
Sets.hh
213
Sets.hh
|
@ -1,213 +0,0 @@
|
||||||
/******************************************************************************/
|
|
||||||
/* SETS ***********************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _H_EBCL_SETS
|
|
||||||
#define _H_EBCL_SETS
|
|
||||||
#include <ebcl/Arrays.hh>
|
|
||||||
#include <ebcl/HashIndex.hh>
|
|
||||||
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 <ebcl/inline/Sets.hh>
|
|
||||||
#include "Sets-inline.hh"
|
|
||||||
|
|
2
ebcl
2
ebcl
|
@ -1 +1 @@
|
||||||
Subproject commit 0bc11d32d746f1075a41137adff51819007d5275
|
Subproject commit cdbc81094d266f007b22825d0e5e836804654381
|
Loading…
Reference in a new issue