206 lines
5.6 KiB
C++
206 lines
5.6 KiB
C++
/******************************************************************************/
|
|
/* HASH TABLES ****************************************************************/
|
|
/******************************************************************************/
|
|
|
|
#ifndef _H_LW_LIB_HASHTABLES
|
|
#define _H_LW_LIB_HASHTABLES
|
|
#include <ebcl/Arrays.hh>
|
|
#include <ebcl/HashIndex.hh>
|
|
namespace ebcl {
|
|
|
|
|
|
// F_KeyMatch< K > - Equality check function for keys
|
|
template< typename K >
|
|
using F_KeyMatch = std::function< bool( K const& , K const& ) >;
|
|
|
|
|
|
// T_DefaultKeyMatch< K > - Default equality check for keys
|
|
template< typename K >
|
|
struct T_DefaultKeyMatch
|
|
{
|
|
static bool keysMatch( K const& , K const& );
|
|
};
|
|
|
|
|
|
/*= KEY / VALUE TABLE ========================================================*/
|
|
|
|
/*
|
|
* T_KeyValueTable - Hash table with separate key and value storage.
|
|
* This class is meant to be used when data with unrelated types need to be
|
|
* associated with each other, e.g. string -> int mapping.
|
|
*/
|
|
|
|
template<
|
|
typename KeyType ,
|
|
typename ValueType
|
|
>
|
|
class T_KeyValueTable
|
|
{
|
|
public:
|
|
typedef F_KeyMatch< KeyType > F_Match;
|
|
|
|
private:
|
|
typedef T_KeyValueTable< KeyType , ValueType > MyType_;
|
|
|
|
F_Match match_;
|
|
T_HashIndex index_;
|
|
T_Array< KeyType > keys_;
|
|
T_Array< ValueType > values_;
|
|
|
|
public:
|
|
M_TEMPLATE_POINTERS( MyType_ );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_KeyValueTable( uint32_t initialSize = T_HashIndex::DEFAULT_SIZE ,
|
|
uint32_t hashSize = T_HashIndex::DEFAULT_SIZE ,
|
|
uint32_t growth = T_HashIndex::DEFAULT_GROWTH ,
|
|
F_Match match = T_DefaultKeyMatch< KeyType >::keysMatch );
|
|
|
|
template< typename K , typename T >
|
|
friend void swap( T_KeyValueTable< K , T >& lhs , T_KeyValueTable< K , T >& rhs );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Add a new value (fails if key already present)
|
|
template<
|
|
typename A , typename B ,
|
|
T_EnableIfTypesMatch< KeyType , A > = true ,
|
|
T_EnableIfTypesMatch< ValueType , B > = true
|
|
> bool add( A&& k , B&& v );
|
|
|
|
// Update an existing value (fails if key not present)
|
|
template<
|
|
typename A ,
|
|
T_EnableIfTypesMatch< ValueType , A > = true
|
|
> bool update( KeyType const& k , A&& v );
|
|
|
|
// Add or modify a key/value pair
|
|
template<
|
|
typename A , typename B ,
|
|
T_EnableIfTypesMatch< KeyType , A > = true ,
|
|
T_EnableIfTypesMatch< ValueType , B > = true
|
|
> void set( A&& k , B&& v );
|
|
|
|
// Remove a key/value pair
|
|
bool remove( KeyType const& k );
|
|
|
|
void clear( );
|
|
void free( );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t size( ) const;
|
|
T_Array< KeyType > const& keys( ) const;
|
|
T_Array< ValueType > const& values( ) const;
|
|
uint32_t indexOf( KeyType const& k ) const;
|
|
bool contains( KeyType const& k ) const;
|
|
|
|
ValueType const * get( KeyType const& k ) const;
|
|
ValueType * get( KeyType const& k );
|
|
|
|
template< typename... ArgTypes >
|
|
ValueType& getOrCreate( KeyType const& k , ArgTypes&&... args );
|
|
|
|
ValueType& operator[] ( uint32_t index );
|
|
ValueType const& operator[] ( uint32_t index ) const;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
private:
|
|
uint32_t find( KeyType const& k , uint32_t hash ) const;
|
|
};
|
|
|
|
template< typename K , typename T >
|
|
void swap( T_KeyValueTable< K , T >& lhs , T_KeyValueTable< K , T >& rhs );
|
|
|
|
|
|
/*= OBJECT TABLE =============================================================*/
|
|
|
|
/*
|
|
* This class is meant to be used to store objects that somehow contain their
|
|
* own keys. Of course, modifying one of these objects' key after it's been
|
|
* inserted will cause major SNAFU's.
|
|
*/
|
|
|
|
template<
|
|
typename KeyType ,
|
|
typename ValueType
|
|
>
|
|
class T_ObjectTable
|
|
{
|
|
public:
|
|
typedef F_KeyMatch< KeyType > F_Match;
|
|
typedef std::function< KeyType( ValueType const& ) > F_GetKey;
|
|
|
|
private:
|
|
typedef T_ObjectTable< KeyType , ValueType > MyType_;
|
|
|
|
F_Match match_;
|
|
F_GetKey keyGetter_;
|
|
T_HashIndex index_;
|
|
T_Array< ValueType > values_;
|
|
|
|
public:
|
|
M_TEMPLATE_POINTERS( MyType_ );
|
|
T_ObjectTable( ) = delete;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
T_ObjectTable( F_GetKey keyGetter , uint32_t initialSize = T_HashIndex::DEFAULT_SIZE ,
|
|
uint32_t hashSize = T_HashIndex::DEFAULT_SIZE ,
|
|
uint32_t growth = T_HashIndex::DEFAULT_GROWTH ,
|
|
F_Match match = T_DefaultKeyMatch< KeyType >::keysMatch );
|
|
|
|
template< typename K , typename T >
|
|
friend void swap( T_ObjectTable< K , T >& lhs , T_ObjectTable< K , T >& rhs );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
template<
|
|
typename A ,
|
|
T_EnableIfTypesMatch< ValueType , A > = true
|
|
> bool add( A&& v );
|
|
|
|
template<
|
|
typename A ,
|
|
T_EnableIfTypesMatch< ValueType , A > = true
|
|
> bool update( A&& v );
|
|
|
|
template<
|
|
typename A ,
|
|
T_EnableIfTypesMatch< ValueType , A > = true
|
|
> void set( A&& v );
|
|
|
|
bool remove( KeyType const& k );
|
|
|
|
void clear( );
|
|
void free( );
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
uint32_t size( ) const;
|
|
uint32_t indexOf( KeyType const& k ) const;
|
|
bool contains( KeyType const& k ) const;
|
|
T_Array< KeyType > keys( ) const;
|
|
T_Array< ValueType > const& values( ) const;
|
|
|
|
ValueType const * get( KeyType const& k ) const;
|
|
ValueType * get( KeyType const& k );
|
|
|
|
ValueType& operator[] ( uint32_t index );
|
|
ValueType const& operator[] ( uint32_t index ) const;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
private:
|
|
uint32_t find( KeyType const& k , uint32_t hash ) const;
|
|
};
|
|
|
|
template< typename K , typename T >
|
|
void swap( T_ObjectTable< K , T >& lhs , T_ObjectTable< K , T >& rhs );
|
|
|
|
|
|
}
|
|
#endif // _H_LW_LIB_HASHTABLES
|
|
#include <ebcl/inline/HashTables.hh>
|