2017-11-08 18:00:33 +01:00
|
|
|
/******************************************************************************/
|
|
|
|
/* 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 =================================*/
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-08 18:00:33 +01:00
|
|
|
#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 =====================================*/
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-08 18:00:33 +01:00
|
|
|
#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 ===========================================================*/
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
// In-place version
|
2017-11-08 18:00:33 +01:00
|
|
|
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:
|
2017-11-09 08:51:07 +01:00
|
|
|
::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 ) );
|
2017-11-08 18:00:33 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2017-11-08 18:00:33 +01:00
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
// Heap-allocated implementation
|
2017-11-08 18:00:33 +01:00
|
|
|
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:
|
2017-11-09 08:51:07 +01:00
|
|
|
*(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 ) );
|
2017-11-08 18:00:33 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
/*= T_Set ====================================================================*/
|
2017-11-08 18:00:33 +01:00
|
|
|
|
|
|
|
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 )
|
|
|
|
{
|
2017-11-09 08:51:07 +01:00
|
|
|
handler_( T_SetHelper::INIT , nullptr , nullptr , &storage_ );
|
2017-11-08 18:00:33 +01:00
|
|
|
}
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
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_ );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
2017-11-08 18:00:33 +01:00
|
|
|
|
|
|
|
template< typename Type >
|
|
|
|
T_Set< Type >::~T_Set( )
|
|
|
|
{
|
|
|
|
handler_( T_SetHelper::DESTROY , &storage_ , nullptr , nullptr );
|
|
|
|
}
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-08 18:00:33 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-11-09 08:51:07 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-08 18:00:33 +01:00
|
|
|
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
|