Sets - Prototyping (will be moved to corelib)
This commit is contained in:
parent
b4f448c21f
commit
a6c068988b
2 changed files with 478 additions and 0 deletions
299
Sets-inline.hh
Normal file
299
Sets-inline.hh
Normal file
|
@ -0,0 +1,299 @@
|
|||
/******************************************************************************/
|
||||
/* 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 =================================*/
|
||||
|
||||
#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
|
179
Sets.hh
Normal file
179
Sets.hh
Normal file
|
@ -0,0 +1,179 @@
|
|||
/******************************************************************************/
|
||||
/* SETS ***********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef _H_EBCL_SETS
|
||||
#define _H_EBCL_SETS
|
||||
#include <ebcl/Arrays.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 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 <ebcl/inline/Sets.hh>
|
||||
#include "Sets-inline.hh"
|
||||
|
Loading…
Reference in a new issue