[map] Finally! Just can usd hb_hashmap_t<obj_t, obj_t>

Yay!
This commit is contained in:
Behdad Esfahbod 2022-06-02 11:11:35 -06:00
parent 0ccab339f9
commit 3f78a71ca0
4 changed files with 27 additions and 50 deletions

View File

@ -35,8 +35,7 @@
*/
template <typename K, typename V,
typename v_invalid_t = V,
v_invalid_t vINVALID = std::is_pointer<V>::value ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
bool minus_one = false>
struct hb_hashmap_t
{
hb_hashmap_t () { init (); }
@ -71,19 +70,24 @@ struct hb_hashmap_t
uint32_t is_tombstone_ : 1;
V value;
bool is_used () const { return is_used_; }
void set_used (bool is_used) { is_used_ = is_used; }
bool is_tombstone () const { return is_tombstone_; }
void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
bool is_real () const { return is_used_ && !is_tombstone_; }
template <bool v = minus_one,
hb_enable_if (v == false)>
static V default_value () { return V(); };
template <bool v = minus_one,
hb_enable_if (v == true)>
static V default_value () { return V(-1); };
void clear ()
{
new (std::addressof (key)) K ();
new (std::addressof (value)) V ();
value = hb_coerce<V> (vINVALID);
value = default_value ();
hash = 0;
is_used_ = false;
is_tombstone_ = false;
@ -200,12 +204,12 @@ struct hb_hashmap_t
V get (K key) const
{
if (unlikely (!items)) return hb_coerce<V> (vINVALID);
if (unlikely (!items)) return item_t::default_value ();
unsigned int i = bucket_for (key);
return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce<V> (vINVALID);
return items[i].is_real () && items[i] == key ? items[i].value : item_t::default_value ();
}
void del (K key) { set_with_hash (key, hb_hash (key), hb_coerce<V> (vINVALID), true); }
void del (K key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
/* Has interface. */
typedef V value_t;
@ -214,8 +218,7 @@ struct hb_hashmap_t
{
const V &v = (*this)[k];
if (vp) *vp = v;
const V vinv = hb_coerce<V> (vINVALID);
return v != vinv;
return v != item_t::default_value (); // TODO
}
/* Projection. */
V operator () (K k) const { return get (k); }
@ -398,13 +401,11 @@ struct hb_hashmap_t
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
hb_codepoint_t,
HB_MAP_VALUE_INVALID>
true>
{
using hashmap = hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
hb_codepoint_t,
HB_MAP_VALUE_INVALID>;
true>;
~hb_map_t () = default;
hb_map_t () : hashmap () {}

View File

@ -78,7 +78,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
post::accelerator_t _post (c->plan->source);
hb_hashmap_t<hb_bytes_t, unsigned> glyph_name_to_new_index;
hb_hashmap_t<hb_bytes_t, unsigned, true> glyph_name_to_new_index;
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
{
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);

View File

@ -719,8 +719,7 @@ struct hb_serialize_context_t
hb_vector_t<object_t *> packed;
/* Map view of packed objects. */
hb_hashmap_t<const object_t *, objidx_t,
objidx_t, 0> packed_map;
hb_hashmap_t<const object_t *, objidx_t> packed_map;
};
#endif /* HB_SERIALIZE_HH */

View File

@ -27,11 +27,6 @@
#include "hb-set.hh"
#include <string>
static const std::string invalid{"invalid"};
static const hb_map_t invalid_map{};
static const hb_set_t invalid_set{};
static const hb_vector_t<unsigned> invalid_vector{};
int
main (int argc, char **argv)
{
@ -127,19 +122,19 @@ main (int argc, char **argv)
/* Test class key / value types. */
{
hb_hashmap_t<hb_bytes_t, int, int, 0> m1;
hb_hashmap_t<int, hb_bytes_t, std::nullptr_t, nullptr> m2;
hb_hashmap_t<hb_bytes_t, hb_bytes_t, std::nullptr_t, nullptr> m3;
hb_hashmap_t<hb_bytes_t, int> m1;
hb_hashmap_t<int, hb_bytes_t> m2;
hb_hashmap_t<hb_bytes_t, hb_bytes_t> m3;
assert (m1.get_population () == 0);
assert (m2.get_population () == 0);
assert (m3.get_population () == 0);
}
{
hb_hashmap_t<int, int, int, 0> m0;
hb_hashmap_t<std::string, int, int, 0> m1;
hb_hashmap_t<int, std::string, const std::string*, &invalid> m2;
hb_hashmap_t<std::string, std::string, const std::string*, &invalid> m3;
hb_hashmap_t<int, int> m0;
hb_hashmap_t<std::string, int> m1;
hb_hashmap_t<int, std::string> m2;
hb_hashmap_t<std::string, std::string> m3;
std::string s;
for (unsigned i = 1; i < 1000; i++)
@ -156,67 +151,49 @@ main (int argc, char **argv)
{
using pair = hb_pair_t<hb_codepoint_t, hb_codepoint_t>;
hb_hashmap_t<hb_map_t, hb_map_t, const hb_map_t *, &invalid_map> m1;
hb_hashmap_t<hb_map_t, hb_map_t, std::nullptr_t, nullptr> m2;
hb_hashmap_t<hb_map_t, hb_map_t> m1;
m1.set (hb_map_t (), hb_map_t {});
m2.set (hb_map_t (), hb_map_t {});
m1.set (hb_map_t (), hb_map_t {pair (1u, 2u)});
m2.set (hb_map_t (), hb_map_t {pair (1u, 2u)});
m1.set (hb_map_t {pair (1u, 2u)}, hb_map_t {pair (2u, 3u)});
m2.set (hb_map_t {pair (1u, 2u)}, hb_map_t {pair (2u, 3u)});
assert (m1.get (hb_map_t ()) == hb_map_t {pair (1u, 2u)});
assert (m2.get (hb_map_t ()) == hb_map_t {pair (1u, 2u)});
assert (m1.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)});
assert (m2.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)});
}
/* Test hashing sets. */
{
hb_hashmap_t<hb_set_t, hb_set_t, const hb_set_t *, &invalid_set> m1;
hb_hashmap_t<hb_set_t, hb_set_t, std::nullptr_t, nullptr> m2;
hb_hashmap_t<hb_set_t, hb_set_t> m1;
m1.set (hb_set_t (), hb_set_t ());
m2.set (hb_set_t (), hb_set_t ());
m1.set (hb_set_t (), hb_set_t {1});
m2.set (hb_set_t (), hb_set_t {1});
m1.set (hb_set_t {1, 1000}, hb_set_t {2});
m2.set (hb_set_t {1, 1000}, hb_set_t {2});
assert (m1.get (hb_set_t ()) == hb_set_t {1});
assert (m2.get (hb_set_t ()) == hb_set_t {1});
assert (m1.get (hb_set_t {1000, 1}) == hb_set_t {2});
assert (m2.get (hb_set_t {1000, 1}) == hb_set_t {2});
}
/* Test hashing vectors. */
{
using vector_t = hb_vector_t<unsigned>;
hb_hashmap_t<vector_t, vector_t, const vector_t *, &invalid_vector> m1;
hb_hashmap_t<vector_t, vector_t, std::nullptr_t, nullptr> m2;
hb_hashmap_t<vector_t, vector_t> m1;
m1.set (vector_t (), vector_t ());
m2.set (vector_t (), vector_t ());
m1.set (vector_t (), vector_t {1});
m2.set (vector_t (), vector_t {1});
m1.set (vector_t {1}, vector_t {2});
m2.set (vector_t {1}, vector_t {2});
assert (m1.get (vector_t ()) == vector_t {1});
assert (m2.get (vector_t ()) == vector_t {1});
assert (m1.get (vector_t {1}) == vector_t {2});
assert (m2.get (vector_t {1}) == vector_t {2});
}
/* Test hb::shared_ptr. */