From 997d9cc466abfb9031f46d1baef5a2cb3164f7cc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 Jun 2022 18:04:12 -0600 Subject: [PATCH] [map] Make unique_ptr hashable --- src/hb-bimap.hh | 3 ++- src/hb-map.hh | 24 ++++++++++++------------ src/hb-ot-color-cpal-table.hh | 4 ++-- src/hb-ot-layout-common.hh | 4 ++-- src/hb-ot-layout-gsubgpos.hh | 7 +++---- src/hb-ot-layout.cc | 4 ++-- src/hb-ot-post-table-v2subset.hh | 4 +++- src/hb-repacker.hh | 16 ++++++++-------- src/test-map.cc | 8 ++++++++ 9 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/hb-bimap.hh b/src/hb-bimap.hh index 8ce4a5e80..8e8c98871 100644 --- a/src/hb-bimap.hh +++ b/src/hb-bimap.hh @@ -64,7 +64,8 @@ struct hb_bimap_t hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); } hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); } - bool has (hb_codepoint_t lhs, hb_codepoint_t *vp = nullptr) const { return forw_map.has (lhs, vp); } + bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); } + void del (hb_codepoint_t lhs) { diff --git a/src/hb-map.hh b/src/hb-map.hh index 262954c34..028e4654b 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -77,10 +77,10 @@ struct hb_hashmap_t template - static V default_value () { return V(); }; + static const V& default_value () { return Null(V); }; template - static V default_value () { return V(-1); }; + static const V& default_value () { static const V minus_1 = -1; return minus_1; }; void clear () { @@ -197,10 +197,10 @@ struct hb_hashmap_t return true; } - bool set (K key, const V &value) { return set_with_hash (key, hb_hash (key), value); } - bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); } + template + bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward (value)); } - V get (K key) const + const V& get (K key) const { if (unlikely (!items)) return item_t::default_value (); unsigned int i = bucket_for (key); @@ -212,22 +212,22 @@ struct hb_hashmap_t /* Has interface. */ typedef V value_t; value_t operator [] (K k) const { return get (k); } - bool has (K key, V *vp = nullptr) const + bool has (K key, const V **vp = nullptr) const { if (unlikely (!items)) { - if (vp) *vp = item_t::default_value (); + if (vp) *vp = &item_t::default_value (); return false; } unsigned int i = bucket_for (key); if (items[i].is_real () && items[i] == key) { - if (vp) *vp = items[i].value; + if (vp) *vp = &items[i].value; return true; } else { - if (vp) *vp = item_t::default_value (); + if (vp) *vp = &item_t::default_value (); return false; } } @@ -320,7 +320,7 @@ struct hb_hashmap_t } items[i].key = key; - items[i].value = value; + items[i].value = std::forward (value); items[i].hash = hash; items[i].set_used (true); items[i].set_tombstone (is_delete); @@ -332,12 +332,12 @@ struct hb_hashmap_t return true; } - unsigned int bucket_for (K key) const + unsigned int bucket_for (const K &key) const { return bucket_for_hash (key, hb_hash (key)); } - unsigned int bucket_for_hash (K key, uint32_t hash) const + unsigned int bucket_for_hash (const K &key, uint32_t hash) const { hash &= 0x3FFFFFFF; // We only store lower 30bit of hash unsigned int i = hash % prime; diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index 201fa3e46..bcab77f79 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -97,10 +97,10 @@ struct CPALV1Tail c->push (); for (const auto _ : colorLabels) { - hb_codepoint_t v; + const hb_codepoint_t *v; if (!color_index_map->has (_, &v)) continue; NameID new_color_idx; - new_color_idx = v; + new_color_idx = *v; if (!c->copy (new_color_idx)) { c->pop_discard (); diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index f9a11657d..a195363d7 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -659,8 +659,8 @@ struct LangSys auto *out = c->serializer->start_embed (*this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - unsigned v; - out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? v : 0xFFFFu; + const unsigned *v; + out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; if (!l->visitFeatureIndex (featureIndex.len)) return_trace (false); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 276a3601c..b76b43139 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -111,8 +111,7 @@ struct hb_closure_context_t : if (!done_lookups_glyph_set->has (lookup_index)) { - hb::shared_ptr empty_set {hb_set_create ()}; - if (unlikely (!done_lookups_glyph_set->set (lookup_index, empty_set))) + if (unlikely (!done_lookups_glyph_set->set (lookup_index, hb::unique_ptr {hb_set_create ()}))) return true; } @@ -168,7 +167,7 @@ struct hb_closure_context_t : hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, hb_map_t *done_lookups_glyph_count_, - hb_hashmap_t> *done_lookups_glyph_set_, + hb_hashmap_t> *done_lookups_glyph_set_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), @@ -192,7 +191,7 @@ struct hb_closure_context_t : private: hb_map_t *done_lookups_glyph_count; - hb_hashmap_t> *done_lookups_glyph_set; + hb_hashmap_t> *done_lookups_glyph_set; unsigned int lookup_count = 0; }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index f5031be81..35e887ba3 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1501,7 +1501,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_set_t *glyphs /* OUT */) { hb_map_t done_lookups_glyph_count; - hb_hashmap_t> done_lookups_glyph_set; + hb_hashmap_t> done_lookups_glyph_set; OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); @@ -1526,7 +1526,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, hb_set_t *glyphs /* OUT */) { hb_map_t done_lookups_glyph_count; - hb_hashmap_t> done_lookups_glyph_set; + hb_hashmap_t> done_lookups_glyph_set; OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const GSUB& gsub = *face->table.GSUB->table; diff --git a/src/hb-ot-post-table-v2subset.hh b/src/hb-ot-post-table-v2subset.hh index 718b09d7e..c8a4429eb 100644 --- a/src/hb-ot-post-table-v2subset.hh +++ b/src/hb-ot-post-table-v2subset.hh @@ -85,9 +85,11 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const unsigned old_index = glyphNameIndex[old_gid]; unsigned new_index; + const unsigned *new_index2; if (old_index <= 257) new_index = old_index; - else if (!old_new_index_map.has (old_index, &new_index)) + else if (!old_new_index_map.has (old_index, &new_index2)) { + new_index = *new_index2; hb_bytes_t s = _post.find_glyph_name (old_gid); new_index = glyph_name_to_new_index.get (s); if (new_index == (unsigned)-1) diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh index 66dce8df8..c9075fa1e 100644 --- a/src/hb-repacker.hh +++ b/src/hb-repacker.hh @@ -430,8 +430,8 @@ struct graph_t auto new_subgraph = + subgraph.keys () | hb_map([&] (unsigned node_idx) { - unsigned v; - if (index_map.has (node_idx, &v)) return v; + const unsigned *v; + if (index_map.has (node_idx, &v)) return *v; return node_idx; }) ; @@ -443,11 +443,11 @@ struct graph_t unsigned next = HB_SET_VALUE_INVALID; while (roots.next (&next)) { - unsigned v; + const unsigned *v; if (index_map.has (next, &v)) { roots.del (next); - roots.add (v); + roots.add (*v); } } @@ -458,10 +458,10 @@ struct graph_t { for (const auto& link : vertices_[node_idx].obj.all_links ()) { - unsigned v; + const unsigned *v; if (subgraph.has (link.objidx, &v)) { - subgraph.set (link.objidx, v + 1); + subgraph.set (link.objidx, *v + 1); continue; } subgraph.set (link.objidx, 1); @@ -943,11 +943,11 @@ struct graph_t { for (auto& link : vertices_[i].obj.all_links_writer ()) { - unsigned v; + const unsigned *v; if (!id_map.has (link.objidx, &v)) continue; if (only_wide && !(link.width == 4 && !link.is_signed)) continue; - reassign_link (link, i, v); + reassign_link (link, i, *v); } } } diff --git a/src/test-map.cc b/src/test-map.cc index c4fdf45c1..9eef49e88 100644 --- a/src/test-map.cc +++ b/src/test-map.cc @@ -195,6 +195,14 @@ main (int argc, char **argv) m.get (hb::shared_ptr ()); m.get (hb::shared_ptr (hb_set_get_empty ())); } + /* Test hb::unique_ptr. */ + hb_hash (hb::unique_ptr ()); + { + hb_hashmap_t, hb::unique_ptr> m; + + m.get (hb::unique_ptr ()); + m.get (hb::unique_ptr (hb_set_get_empty ())); + } return 0; }