demotool/Sets.hh

179 lines
4.3 KiB
C++

/******************************************************************************/
/* 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"