diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 055516543..330d85e56 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -211,8 +211,11 @@ struct } HB_FUNCOBJ (hb_bool); -template T hb_coerce (const T v) { return v; } -template T hb_coerce (const T *v) { return *v; } +template +T hb_coerce (const T v) { return v; } +template , hb_decay) && hb_is_pointer(V))> +T hb_coerce (const V v) { return *v; } struct { diff --git a/src/hb-map.hh b/src/hb-map.hh index ccba8bd6e..22341953c 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -61,8 +61,6 @@ struct hb_hashmap_t hb_copy (o, *this); } - static_assert (std::is_trivially_copyable::value, ""); - static_assert (std::is_trivially_copyable::value, ""); static_assert (std::is_trivially_destructible::value, ""); static_assert (std::is_trivially_destructible::value, ""); @@ -75,9 +73,9 @@ struct hb_hashmap_t void clear () { new (hb_addressof (key)) K (); - key = kINVALID; + key = hb_coerce (kINVALID); new (hb_addressof (value)) V (); - value = vINVALID; + value = hb_coerce (vINVALID); hash = 0; } @@ -85,19 +83,19 @@ struct hb_hashmap_t bool operator == (const item_t &o) { return *this == o.key; } bool is_unused () const { - const K inv = kINVALID; + const K inv = hb_coerce (kINVALID); return key == inv; } bool is_tombstone () const { - const K kinv = kINVALID; - const V vinv = vINVALID; + const K kinv = hb_coerce (kINVALID); + const V vinv = hb_coerce (vINVALID); return key != kinv && value == vinv; } bool is_real () const { - const K kinv = kINVALID; - const V vinv = vINVALID; + const K kinv = hb_coerce (kINVALID); + const V vinv = hb_coerce (vINVALID); return key != kinv && value != vinv; } hb_pair_t get_pair() const { return hb_pair_t (key, value); } @@ -196,12 +194,12 @@ struct hb_hashmap_t V get (K key) const { - if (unlikely (!items)) return vINVALID; + if (unlikely (!items)) return hb_coerce (vINVALID); unsigned int i = bucket_for (key); - return items[i].is_real () && items[i] == key ? items[i].value : vINVALID; + return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce (vINVALID); } - void del (K key) { set (key, vINVALID); } + void del (K key) { set (key, hb_coerce (vINVALID)); } /* Has interface. */ typedef V value_t; @@ -210,7 +208,7 @@ struct hb_hashmap_t { V v = (*this)[k]; if (vp) *vp = v; - const V vinv = vINVALID; + const V vinv = hb_coerce (vINVALID); return v != vinv; } /* Projection. */ @@ -266,12 +264,12 @@ struct hb_hashmap_t bool set_with_hash (K key, uint32_t hash, VV&& value) { if (unlikely (!successful)) return false; - const K kinv = kINVALID; + const K kinv = hb_coerce (kINVALID); if (unlikely (key == kinv)) return true; if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; unsigned int i = bucket_for_hash (key, hash); - const V vinv = vINVALID; + const V vinv = hb_coerce (vINVALID); if (value == vinv && items[i].key != key) return true; /* Trying to delete non-existent key. */