[map] Make unique_ptr hashable

This commit is contained in:
Behdad Esfahbod 2022-06-02 18:04:12 -06:00
parent 8bb2a3326e
commit 997d9cc466
9 changed files with 42 additions and 32 deletions

View File

@ -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)
{

View File

@ -77,10 +77,10 @@ struct hb_hashmap_t
template <bool v = minus_one,
hb_enable_if (v == false)>
static V default_value () { return V(); };
static const V& default_value () { return Null(V); };
template <bool v = minus_one,
hb_enable_if (v == true)>
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 <typename VV>
bool set (K key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (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<VV> (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;

View File

@ -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<NameID> (new_color_idx))
{
c->pop_discard ();

View File

@ -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);

View File

@ -111,8 +111,7 @@ struct hb_closure_context_t :
if (!done_lookups_glyph_set->has (lookup_index))
{
hb::shared_ptr<hb_set_t> 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_t> {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<unsigned, hb::shared_ptr<hb_set_t>> *done_lookups_glyph_set_,
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_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<unsigned, hb::shared_ptr<hb_set_t>> *done_lookups_glyph_set;
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *done_lookups_glyph_set;
unsigned int lookup_count = 0;
};

View File

@ -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<unsigned, hb::shared_ptr<hb_set_t>> done_lookups_glyph_set;
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_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<unsigned, hb::shared_ptr<hb_set_t>> done_lookups_glyph_set;
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_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;

View File

@ -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)

View File

@ -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);
}
}
}

View File

@ -195,6 +195,14 @@ main (int argc, char **argv)
m.get (hb::shared_ptr<hb_set_t> ());
m.get (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
}
/* Test hb::unique_ptr. */
hb_hash (hb::unique_ptr<hb_set_t> ());
{
hb_hashmap_t<hb::unique_ptr<hb_set_t>, hb::unique_ptr<hb_set_t>> m;
m.get (hb::unique_ptr<hb_set_t> ());
m.get (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
}
return 0;
}