[map] Templatize hb_map_t
Template name is hb_hashmap_t<K,V>.
This commit is contained in:
parent
4b7f4dbc0c
commit
c98f51da71
|
@ -31,22 +31,28 @@
|
|||
|
||||
|
||||
/*
|
||||
* hb_map_t
|
||||
* hb_hashmap_t
|
||||
*/
|
||||
|
||||
struct hb_map_t
|
||||
template <typename K, typename V,
|
||||
K kINVALID = hb_is_pointer (K) ? 0 : (K) -1,
|
||||
V vINVALID = hb_is_pointer (V) ? 0 : (V) -1>
|
||||
struct hb_hashmap_t
|
||||
{
|
||||
HB_NO_COPY_ASSIGN (hb_map_t);
|
||||
hb_map_t () { init (); }
|
||||
~hb_map_t () { fini (); }
|
||||
HB_NO_COPY_ASSIGN (hb_hashmap_t);
|
||||
hb_hashmap_t () { init (); }
|
||||
~hb_hashmap_t () { fini (); }
|
||||
|
||||
static_assert (hb_is_integer (K) || hb_is_pointer (K), "");
|
||||
static_assert (hb_is_integer (V) || hb_is_pointer (V), "");
|
||||
|
||||
struct item_t
|
||||
{
|
||||
hb_codepoint_t key;
|
||||
hb_codepoint_t value;
|
||||
K key;
|
||||
V value;
|
||||
|
||||
bool is_unused () const { return key == INVALID; }
|
||||
bool is_tombstone () const { return key != INVALID && value == INVALID; }
|
||||
bool is_unused () const { return key == kINVALID; }
|
||||
bool is_tombstone () const { return key != kINVALID && value == vINVALID; }
|
||||
};
|
||||
|
||||
hb_object_header_t header;
|
||||
|
@ -110,7 +116,7 @@ struct hb_map_t
|
|||
/* Insert back old items. */
|
||||
if (old_items)
|
||||
for (unsigned int i = 0; i < old_size; i++)
|
||||
if (old_items[i].key != INVALID && old_items[i].value != INVALID)
|
||||
if (old_items[i].key != kINVALID && old_items[i].value != vINVALID)
|
||||
set (old_items[i].key, old_items[i].value);
|
||||
|
||||
free (old_items);
|
||||
|
@ -118,14 +124,14 @@ struct hb_map_t
|
|||
return true;
|
||||
}
|
||||
|
||||
void set (hb_codepoint_t key, hb_codepoint_t value)
|
||||
void set (K key, V value)
|
||||
{
|
||||
if (unlikely (!successful)) return;
|
||||
if (unlikely (key == INVALID)) return;
|
||||
if (unlikely (key == kINVALID)) return;
|
||||
if ((occupancy + occupancy / 2) >= mask && !resize ()) return;
|
||||
unsigned int i = bucket_for (key);
|
||||
|
||||
if (value == INVALID && items[i].key != key)
|
||||
if (value == vINVALID && items[i].key != key)
|
||||
return; /* Trying to delete non-existent key. */
|
||||
|
||||
if (!items[i].is_unused ())
|
||||
|
@ -143,24 +149,22 @@ struct hb_map_t
|
|||
population++;
|
||||
|
||||
}
|
||||
hb_codepoint_t get (hb_codepoint_t key) const
|
||||
V get (K key) const
|
||||
{
|
||||
if (unlikely (!items)) return INVALID;
|
||||
if (unlikely (!items)) return vINVALID;
|
||||
unsigned int i = bucket_for (key);
|
||||
return items[i].key == key ? items[i].value : INVALID;
|
||||
return items[i].key == key ? items[i].value : vINVALID;
|
||||
}
|
||||
|
||||
void del (hb_codepoint_t key) { set (key, INVALID); }
|
||||
|
||||
static constexpr hb_codepoint_t INVALID = HB_MAP_VALUE_INVALID;
|
||||
void del (K key) { set (key, vINVALID); }
|
||||
|
||||
/* Has interface. */
|
||||
static constexpr hb_codepoint_t SENTINEL = INVALID;
|
||||
typedef hb_codepoint_t value_t;
|
||||
value_t operator [] (hb_codepoint_t k) const { return get (k); }
|
||||
bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
|
||||
static constexpr V SENTINEL = vINVALID;
|
||||
typedef V value_t;
|
||||
value_t operator [] (K k) const { return get (k); }
|
||||
bool has (K k) const { return (*this)[k] != SENTINEL; }
|
||||
/* Projection. */
|
||||
hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
|
||||
V operator () (K k) const { return get (k); }
|
||||
|
||||
void clear ()
|
||||
{
|
||||
|
@ -174,20 +178,20 @@ struct hb_map_t
|
|||
|
||||
protected:
|
||||
|
||||
unsigned int bucket_for (hb_codepoint_t key) const
|
||||
unsigned int bucket_for (K key) const
|
||||
{
|
||||
unsigned int i = hb_hash (key) % prime;
|
||||
unsigned int step = 0;
|
||||
unsigned int tombstone = INVALID;
|
||||
unsigned int tombstone = (unsigned) -1;
|
||||
while (!items[i].is_unused ())
|
||||
{
|
||||
if (items[i].key == key)
|
||||
return i;
|
||||
if (tombstone == INVALID && items[i].is_tombstone ())
|
||||
if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
|
||||
tombstone = i;
|
||||
i = (i + ++step) & mask;
|
||||
}
|
||||
return tombstone == INVALID ? i : tombstone;
|
||||
return tombstone == (unsigned) -1 ? i : tombstone;
|
||||
}
|
||||
|
||||
static unsigned int prime_for (unsigned int shift)
|
||||
|
@ -242,5 +246,10 @@ struct hb_map_t
|
|||
}
|
||||
};
|
||||
|
||||
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
|
||||
hb_codepoint_t,
|
||||
HB_MAP_VALUE_INVALID,
|
||||
HB_MAP_VALUE_INVALID> {};
|
||||
|
||||
|
||||
#endif /* HB_MAP_HH */
|
||||
|
|
Loading…
Reference in New Issue