From 394f772937851f10ef05245e32279cf08ca8399d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 19 Nov 2021 11:49:23 -0700 Subject: [PATCH] [map] Allow storing classes in the hashmap Fixes https://github.com/harfbuzz/harfbuzz/issues/3293 The trick was to change the type of the invalid key/value to be non-class. --- src/hb-map.hh | 22 +++++++++++++++------- src/hb-ot-layout-common.hh | 8 ++++---- src/hb-ot-layout-gsubgpos.hh | 8 ++++---- src/hb-ot-layout.cc | 4 ++-- src/hb-serialize.hh | 4 +++- src/hb-set.hh | 6 +++--- src/hb-subset-plan.cc | 2 +- src/hb-subset-plan.hh | 4 ++-- src/test-map.cc | 7 +++++++ 9 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index bb4a0eb5d..793dcf22c 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -35,8 +35,10 @@ */ template ::value ? hb_int_min (K) : (K) -1, - V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed::value ? hb_int_min (V) : (V) -1> + typename k_invalid_t = K, + typename v_invalid_t = V, + k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed::value ? hb_int_min (K) : (K) -1, + v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed::value ? hb_int_min (V) : (V) -1> struct hb_hashmap_t { static constexpr K INVALID_KEY = kINVALID; @@ -62,8 +64,10 @@ struct hb_hashmap_t hb_copy (o, *this); } - static_assert (std::is_integral::value || hb_is_pointer (K), ""); - static_assert (std::is_integral::value || hb_is_pointer (V), ""); + 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, ""); struct item_t { @@ -347,20 +351,24 @@ struct hb_hashmap_t */ struct hb_map_t : hb_hashmap_t { using hashmap = hb_hashmap_t; hb_map_t () = default; ~hb_map_t () = default; - hb_map_t (hb_map_t& o) = default; - hb_map_t& operator= (const hb_map_t& other) = default; - hb_map_t& operator= (hb_map_t&& other) = default; + hb_map_t (hb_map_t&) = default; + hb_map_t& operator= (const hb_map_t&) = default; + hb_map_t& operator= (hb_map_t&&) = default; hb_map_t (std::initializer_list> lst) : hashmap (lst) {} template diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 5b61e6408..882c3ae96 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -98,7 +98,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, struct hb_prune_langsys_context_t { hb_prune_langsys_context_t (const void *table_, - hb_hashmap_t *script_langsys_map_, + hb_hashmap_t *script_langsys_map_, const hb_map_t *duplicate_feature_map_, hb_set_t *new_collected_feature_indexes_) :table (table_), @@ -137,7 +137,7 @@ struct hb_prune_langsys_context_t public: const void *table; - hb_hashmap_t *script_langsys_map; + hb_hashmap_t *script_langsys_map; const hb_map_t *duplicate_feature_map; hb_set_t *new_feature_indexes; @@ -179,14 +179,14 @@ struct hb_subset_layout_context_t : hb_subset_context_t *subset_context; const hb_tag_t table_tag; const hb_map_t *lookup_index_map; - const hb_hashmap_t *script_langsys_map; + const hb_hashmap_t *script_langsys_map; const hb_map_t *feature_index_map; unsigned cur_script_index; hb_subset_layout_context_t (hb_subset_context_t *c_, hb_tag_t tag_, hb_map_t *lookup_map_, - hb_hashmap_t *script_langsys_map_, + hb_hashmap_t *script_langsys_map_, hb_map_t *feature_index_map_) : subset_context (c_), table_tag (tag_), diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index c0ed2bcc0..f5657ec7f 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -163,7 +163,7 @@ struct hb_closure_context_t : hb_set_t *glyphs_, hb_set_t *cur_intersected_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 +192,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; }; @@ -3631,7 +3631,7 @@ struct GSUBGPOS } void prune_langsys (const hb_map_t *duplicate_feature_map, - hb_hashmap_t *script_langsys_map, + hb_hashmap_t *script_langsys_map, hb_set_t *new_feature_indexes /* OUT */) const { hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes); @@ -3689,7 +3689,7 @@ struct GSUBGPOS hb_map_t *duplicate_feature_map /* OUT */) const { if (feature_indices->is_empty ()) return; - hb_hashmap_t unique_features; + hb_hashmap_t unique_features; //find out duplicate features after subset for (unsigned i : feature_indices->iter ()) { diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index fbdedd0e2..4e1d23eba 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1493,7 +1493,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, { hb_set_t cur_intersected_glyphs; 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, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); @@ -1522,7 +1522,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, { hb_set_t cur_intersected_glyphs; 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, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const OT::GSUB& gsub = *face->table.GSUB->table; diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 57689916f..d22ae0608 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -652,7 +652,9 @@ struct hb_serialize_context_t hb_vector_t packed; /* Map view of packed objects. */ - hb_hashmap_t packed_map; + hb_hashmap_t packed_map; }; #endif /* HB_SERIALIZE_HH */ diff --git a/src/hb-set.hh b/src/hb-set.hh index 884142718..af02e9e12 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -157,9 +157,9 @@ struct hb_set_t : hb_sparseset_t { hb_set_t () = default; ~hb_set_t () = default; - hb_set_t (hb_set_t& o) = default; - hb_set_t& operator= (const hb_set_t& other) = default; - hb_set_t& operator= (hb_set_t&& other) = default; + hb_set_t (hb_set_t&) = default; + hb_set_t& operator= (const hb_set_t&) = default; + hb_set_t& operator= (hb_set_t&&) = default; hb_set_t (std::initializer_list lst) : hb_sparseset_t (lst) {} template diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 1e195ff66..cc793afa7 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -41,7 +41,7 @@ #include "hb-ot-math-table.hh" -typedef hb_hashmap_t script_langsys_map; +typedef hb_hashmap_t script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index c30feeb42..c0232480b 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -84,8 +84,8 @@ struct hb_subset_plan_t hb_map_t *gpos_lookups; //active langsys we'd like to retain - hb_hashmap_t *gsub_langsys; - hb_hashmap_t *gpos_langsys; + hb_hashmap_t *gsub_langsys; + hb_hashmap_t *gpos_langsys; //active features after removing redundant langsys and prune_features hb_map_t *gsub_features; diff --git a/src/test-map.cc b/src/test-map.cc index 5761cc8d6..8c8f0a83b 100644 --- a/src/test-map.cc +++ b/src/test-map.cc @@ -98,5 +98,12 @@ main (int argc, char **argv) assert (v2.get_population () == 2); } + /* Test class key / value types. */ + { + hb_hashmap_t m1; + hb_hashmap_t m2; + hb_hashmap_t m3; + } + return 0; }