[map] Make unique_ptr hashable
This commit is contained in:
parent
8bb2a3326e
commit
997d9cc466
|
@ -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 backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
|
||||||
|
|
||||||
hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
|
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)
|
void del (hb_codepoint_t lhs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,10 +77,10 @@ struct hb_hashmap_t
|
||||||
|
|
||||||
template <bool v = minus_one,
|
template <bool v = minus_one,
|
||||||
hb_enable_if (v == false)>
|
hb_enable_if (v == false)>
|
||||||
static V default_value () { return V(); };
|
static const V& default_value () { return Null(V); };
|
||||||
template <bool v = minus_one,
|
template <bool v = minus_one,
|
||||||
hb_enable_if (v == true)>
|
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 ()
|
void clear ()
|
||||||
{
|
{
|
||||||
|
@ -197,10 +197,10 @@ struct hb_hashmap_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set (K key, const V &value) { return set_with_hash (key, hb_hash (key), value); }
|
template <typename VV>
|
||||||
bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); }
|
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 ();
|
if (unlikely (!items)) return item_t::default_value ();
|
||||||
unsigned int i = bucket_for (key);
|
unsigned int i = bucket_for (key);
|
||||||
|
@ -212,22 +212,22 @@ struct hb_hashmap_t
|
||||||
/* Has interface. */
|
/* Has interface. */
|
||||||
typedef V value_t;
|
typedef V value_t;
|
||||||
value_t operator [] (K k) const { return get (k); }
|
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 (unlikely (!items))
|
||||||
{
|
{
|
||||||
if (vp) *vp = item_t::default_value ();
|
if (vp) *vp = &item_t::default_value ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned int i = bucket_for (key);
|
unsigned int i = bucket_for (key);
|
||||||
if (items[i].is_real () && items[i] == key)
|
if (items[i].is_real () && items[i] == key)
|
||||||
{
|
{
|
||||||
if (vp) *vp = items[i].value;
|
if (vp) *vp = &items[i].value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vp) *vp = item_t::default_value ();
|
if (vp) *vp = &item_t::default_value ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ struct hb_hashmap_t
|
||||||
}
|
}
|
||||||
|
|
||||||
items[i].key = key;
|
items[i].key = key;
|
||||||
items[i].value = value;
|
items[i].value = std::forward<VV> (value);
|
||||||
items[i].hash = hash;
|
items[i].hash = hash;
|
||||||
items[i].set_used (true);
|
items[i].set_used (true);
|
||||||
items[i].set_tombstone (is_delete);
|
items[i].set_tombstone (is_delete);
|
||||||
|
@ -332,12 +332,12 @@ struct hb_hashmap_t
|
||||||
return true;
|
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));
|
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
|
hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
|
||||||
unsigned int i = hash % prime;
|
unsigned int i = hash % prime;
|
||||||
|
|
|
@ -97,10 +97,10 @@ struct CPALV1Tail
|
||||||
c->push ();
|
c->push ();
|
||||||
for (const auto _ : colorLabels)
|
for (const auto _ : colorLabels)
|
||||||
{
|
{
|
||||||
hb_codepoint_t v;
|
const hb_codepoint_t *v;
|
||||||
if (!color_index_map->has (_, &v)) continue;
|
if (!color_index_map->has (_, &v)) continue;
|
||||||
NameID new_color_idx;
|
NameID new_color_idx;
|
||||||
new_color_idx = v;
|
new_color_idx = *v;
|
||||||
if (!c->copy<NameID> (new_color_idx))
|
if (!c->copy<NameID> (new_color_idx))
|
||||||
{
|
{
|
||||||
c->pop_discard ();
|
c->pop_discard ();
|
||||||
|
|
|
@ -659,8 +659,8 @@ struct LangSys
|
||||||
auto *out = c->serializer->start_embed (*this);
|
auto *out = c->serializer->start_embed (*this);
|
||||||
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
unsigned v;
|
const unsigned *v;
|
||||||
out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? v : 0xFFFFu;
|
out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
|
||||||
|
|
||||||
if (!l->visitFeatureIndex (featureIndex.len))
|
if (!l->visitFeatureIndex (featureIndex.len))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
|
@ -111,8 +111,7 @@ struct hb_closure_context_t :
|
||||||
|
|
||||||
if (!done_lookups_glyph_set->has (lookup_index))
|
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, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
|
||||||
if (unlikely (!done_lookups_glyph_set->set (lookup_index, empty_set)))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +167,7 @@ struct hb_closure_context_t :
|
||||||
hb_closure_context_t (hb_face_t *face_,
|
hb_closure_context_t (hb_face_t *face_,
|
||||||
hb_set_t *glyphs_,
|
hb_set_t *glyphs_,
|
||||||
hb_map_t *done_lookups_glyph_count_,
|
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) :
|
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
|
||||||
face (face_),
|
face (face_),
|
||||||
glyphs (glyphs_),
|
glyphs (glyphs_),
|
||||||
|
@ -192,7 +191,7 @@ struct hb_closure_context_t :
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hb_map_t *done_lookups_glyph_count;
|
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;
|
unsigned int lookup_count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1501,7 +1501,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||||
hb_set_t *glyphs /* OUT */)
|
hb_set_t *glyphs /* OUT */)
|
||||||
{
|
{
|
||||||
hb_map_t done_lookups_glyph_count;
|
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);
|
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);
|
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_set_t *glyphs /* OUT */)
|
||||||
{
|
{
|
||||||
hb_map_t done_lookups_glyph_count;
|
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);
|
OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||||
const GSUB& gsub = *face->table.GSUB->table;
|
const GSUB& gsub = *face->table.GSUB->table;
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,11 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
|
||||||
unsigned old_index = glyphNameIndex[old_gid];
|
unsigned old_index = glyphNameIndex[old_gid];
|
||||||
|
|
||||||
unsigned new_index;
|
unsigned new_index;
|
||||||
|
const unsigned *new_index2;
|
||||||
if (old_index <= 257) new_index = old_index;
|
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);
|
hb_bytes_t s = _post.find_glyph_name (old_gid);
|
||||||
new_index = glyph_name_to_new_index.get (s);
|
new_index = glyph_name_to_new_index.get (s);
|
||||||
if (new_index == (unsigned)-1)
|
if (new_index == (unsigned)-1)
|
||||||
|
|
|
@ -430,8 +430,8 @@ struct graph_t
|
||||||
auto new_subgraph =
|
auto new_subgraph =
|
||||||
+ subgraph.keys ()
|
+ subgraph.keys ()
|
||||||
| hb_map([&] (unsigned node_idx) {
|
| hb_map([&] (unsigned node_idx) {
|
||||||
unsigned v;
|
const unsigned *v;
|
||||||
if (index_map.has (node_idx, &v)) return v;
|
if (index_map.has (node_idx, &v)) return *v;
|
||||||
return node_idx;
|
return node_idx;
|
||||||
})
|
})
|
||||||
;
|
;
|
||||||
|
@ -443,11 +443,11 @@ struct graph_t
|
||||||
unsigned next = HB_SET_VALUE_INVALID;
|
unsigned next = HB_SET_VALUE_INVALID;
|
||||||
while (roots.next (&next))
|
while (roots.next (&next))
|
||||||
{
|
{
|
||||||
unsigned v;
|
const unsigned *v;
|
||||||
if (index_map.has (next, &v))
|
if (index_map.has (next, &v))
|
||||||
{
|
{
|
||||||
roots.del (next);
|
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 ())
|
for (const auto& link : vertices_[node_idx].obj.all_links ())
|
||||||
{
|
{
|
||||||
unsigned v;
|
const unsigned *v;
|
||||||
if (subgraph.has (link.objidx, &v))
|
if (subgraph.has (link.objidx, &v))
|
||||||
{
|
{
|
||||||
subgraph.set (link.objidx, v + 1);
|
subgraph.set (link.objidx, *v + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
subgraph.set (link.objidx, 1);
|
subgraph.set (link.objidx, 1);
|
||||||
|
@ -943,11 +943,11 @@ struct graph_t
|
||||||
{
|
{
|
||||||
for (auto& link : vertices_[i].obj.all_links_writer ())
|
for (auto& link : vertices_[i].obj.all_links_writer ())
|
||||||
{
|
{
|
||||||
unsigned v;
|
const unsigned *v;
|
||||||
if (!id_map.has (link.objidx, &v)) continue;
|
if (!id_map.has (link.objidx, &v)) continue;
|
||||||
if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
|
if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
|
||||||
|
|
||||||
reassign_link (link, i, v);
|
reassign_link (link, i, *v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> ());
|
||||||
m.get (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue