[map] Finally! Just can usd hb_hashmap_t<obj_t, obj_t>
Yay!
This commit is contained in:
parent
0ccab339f9
commit
3f78a71ca0
|
@ -35,8 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename K, typename V,
|
template <typename K, typename V,
|
||||||
typename v_invalid_t = V,
|
bool minus_one = false>
|
||||||
v_invalid_t vINVALID = std::is_pointer<V>::value ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
|
|
||||||
struct hb_hashmap_t
|
struct hb_hashmap_t
|
||||||
{
|
{
|
||||||
hb_hashmap_t () { init (); }
|
hb_hashmap_t () { init (); }
|
||||||
|
@ -71,19 +70,24 @@ struct hb_hashmap_t
|
||||||
uint32_t is_tombstone_ : 1;
|
uint32_t is_tombstone_ : 1;
|
||||||
V value;
|
V value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool is_used () const { return is_used_; }
|
bool is_used () const { return is_used_; }
|
||||||
void set_used (bool is_used) { is_used_ = is_used; }
|
void set_used (bool is_used) { is_used_ = is_used; }
|
||||||
bool is_tombstone () const { return is_tombstone_; }
|
bool is_tombstone () const { return is_tombstone_; }
|
||||||
void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
|
void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
|
||||||
bool is_real () const { return is_used_ && !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 ()
|
void clear ()
|
||||||
{
|
{
|
||||||
new (std::addressof (key)) K ();
|
new (std::addressof (key)) K ();
|
||||||
new (std::addressof (value)) V ();
|
new (std::addressof (value)) V ();
|
||||||
value = hb_coerce<V> (vINVALID);
|
value = default_value ();
|
||||||
hash = 0;
|
hash = 0;
|
||||||
is_used_ = false;
|
is_used_ = false;
|
||||||
is_tombstone_ = false;
|
is_tombstone_ = false;
|
||||||
|
@ -200,12 +204,12 @@ struct hb_hashmap_t
|
||||||
|
|
||||||
V get (K key) const
|
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);
|
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. */
|
/* Has interface. */
|
||||||
typedef V value_t;
|
typedef V value_t;
|
||||||
|
@ -214,8 +218,7 @@ struct hb_hashmap_t
|
||||||
{
|
{
|
||||||
const V &v = (*this)[k];
|
const V &v = (*this)[k];
|
||||||
if (vp) *vp = v;
|
if (vp) *vp = v;
|
||||||
const V vinv = hb_coerce<V> (vINVALID);
|
return v != item_t::default_value (); // TODO
|
||||||
return v != vinv;
|
|
||||||
}
|
}
|
||||||
/* Projection. */
|
/* Projection. */
|
||||||
V operator () (K k) const { return get (k); }
|
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,
|
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
|
||||||
hb_codepoint_t,
|
hb_codepoint_t,
|
||||||
hb_codepoint_t,
|
true>
|
||||||
HB_MAP_VALUE_INVALID>
|
|
||||||
{
|
{
|
||||||
using hashmap = hb_hashmap_t<hb_codepoint_t,
|
using hashmap = hb_hashmap_t<hb_codepoint_t,
|
||||||
hb_codepoint_t,
|
hb_codepoint_t,
|
||||||
hb_codepoint_t,
|
true>;
|
||||||
HB_MAP_VALUE_INVALID>;
|
|
||||||
|
|
||||||
~hb_map_t () = default;
|
~hb_map_t () = default;
|
||||||
hb_map_t () : hashmap () {}
|
hb_map_t () : hashmap () {}
|
||||||
|
|
|
@ -78,7 +78,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
|
||||||
|
|
||||||
post::accelerator_t _post (c->plan->source);
|
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++)
|
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
|
||||||
{
|
{
|
||||||
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
|
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
|
||||||
|
|
|
@ -719,8 +719,7 @@ struct hb_serialize_context_t
|
||||||
hb_vector_t<object_t *> packed;
|
hb_vector_t<object_t *> packed;
|
||||||
|
|
||||||
/* Map view of packed objects. */
|
/* Map view of packed objects. */
|
||||||
hb_hashmap_t<const object_t *, objidx_t,
|
hb_hashmap_t<const object_t *, objidx_t> packed_map;
|
||||||
objidx_t, 0> packed_map;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HB_SERIALIZE_HH */
|
#endif /* HB_SERIALIZE_HH */
|
||||||
|
|
|
@ -27,11 +27,6 @@
|
||||||
#include "hb-set.hh"
|
#include "hb-set.hh"
|
||||||
#include <string>
|
#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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -127,19 +122,19 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
/* Test class key / value types. */
|
/* Test class key / value types. */
|
||||||
{
|
{
|
||||||
hb_hashmap_t<hb_bytes_t, int, int, 0> m1;
|
hb_hashmap_t<hb_bytes_t, int> m1;
|
||||||
hb_hashmap_t<int, hb_bytes_t, std::nullptr_t, nullptr> m2;
|
hb_hashmap_t<int, hb_bytes_t> m2;
|
||||||
hb_hashmap_t<hb_bytes_t, hb_bytes_t, std::nullptr_t, nullptr> m3;
|
hb_hashmap_t<hb_bytes_t, hb_bytes_t> m3;
|
||||||
assert (m1.get_population () == 0);
|
assert (m1.get_population () == 0);
|
||||||
assert (m2.get_population () == 0);
|
assert (m2.get_population () == 0);
|
||||||
assert (m3.get_population () == 0);
|
assert (m3.get_population () == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
hb_hashmap_t<int, int, int, 0> m0;
|
hb_hashmap_t<int, int> m0;
|
||||||
hb_hashmap_t<std::string, int, int, 0> m1;
|
hb_hashmap_t<std::string, int> m1;
|
||||||
hb_hashmap_t<int, std::string, const std::string*, &invalid> m2;
|
hb_hashmap_t<int, std::string> m2;
|
||||||
hb_hashmap_t<std::string, std::string, const std::string*, &invalid> m3;
|
hb_hashmap_t<std::string, std::string> m3;
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
for (unsigned i = 1; i < 1000; i++)
|
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>;
|
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> m1;
|
||||||
hb_hashmap_t<hb_map_t, hb_map_t, std::nullptr_t, nullptr> m2;
|
|
||||||
|
|
||||||
m1.set (hb_map_t (), hb_map_t {});
|
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)});
|
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)});
|
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 (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 (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. */
|
/* 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> m1;
|
||||||
hb_hashmap_t<hb_set_t, hb_set_t, std::nullptr_t, nullptr> m2;
|
|
||||||
|
|
||||||
m1.set (hb_set_t (), hb_set_t ());
|
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});
|
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});
|
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 (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 (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. */
|
/* Test hashing vectors. */
|
||||||
{
|
{
|
||||||
using vector_t = hb_vector_t<unsigned>;
|
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> m1;
|
||||||
hb_hashmap_t<vector_t, vector_t, std::nullptr_t, nullptr> m2;
|
|
||||||
|
|
||||||
m1.set (vector_t (), vector_t ());
|
m1.set (vector_t (), vector_t ());
|
||||||
m2.set (vector_t (), vector_t ());
|
|
||||||
|
|
||||||
m1.set (vector_t (), vector_t {1});
|
m1.set (vector_t (), vector_t {1});
|
||||||
m2.set (vector_t (), vector_t {1});
|
|
||||||
|
|
||||||
m1.set (vector_t {1}, vector_t {2});
|
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 (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 (m1.get (vector_t {1}) == vector_t {2});
|
||||||
assert (m2.get (vector_t {1}) == vector_t {2});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test hb::shared_ptr. */
|
/* Test hb::shared_ptr. */
|
||||||
|
|
Loading…
Reference in New Issue