Coverage Report

Created: 2024-05-29 15:21

/src/harfbuzz/src/hb-map.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2018  Google, Inc.
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 *
24
 * Google Author(s): Behdad Esfahbod
25
 */
26
27
#ifndef HB_MAP_HH
28
#define HB_MAP_HH
29
30
#include "hb.hh"
31
32
#include "hb-set.hh"
33
34
35
/*
36
 * hb_hashmap_t
37
 */
38
39
extern HB_INTERNAL const hb_codepoint_t minus_1;
40
41
template <typename K, typename V,
42
    bool minus_one = false>
43
struct hb_hashmap_t
44
{
45
195k
  hb_hashmap_t ()  { init (); }
hb_hashmap_t<unsigned int, unsigned int, true>::hb_hashmap_t()
Line
Count
Source
45
191k
  hb_hashmap_t ()  { init (); }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::hb_hashmap_t()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::hb_hashmap_t()
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::hb_hashmap_t()
Line
Count
Source
45
4.02k
  hb_hashmap_t ()  { init (); }
46
195k
  ~hb_hashmap_t () { fini (); }
hb_hashmap_t<unsigned int, unsigned int, true>::~hb_hashmap_t()
Line
Count
Source
46
191k
  ~hb_hashmap_t () { fini (); }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::~hb_hashmap_t()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::~hb_hashmap_t()
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::~hb_hashmap_t()
Line
Count
Source
46
4.02k
  ~hb_hashmap_t () { fini (); }
47
48
  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); }
49
  hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
50
0
  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { reset (); resize (o.population); hb_copy (o, *this); return *this; }
51
0
  hb_hashmap_t& operator= (hb_hashmap_t&& o)  { hb_swap (*this, o); return *this; }
52
53
  hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
54
  {
55
    for (auto&& item : lst)
56
      set (item.first, item.second);
57
  }
58
  template <typename Iterable,
59
      hb_requires (hb_is_iterable (Iterable))>
60
  hb_hashmap_t (const Iterable &o) : hb_hashmap_t ()
61
  {
62
    auto iter = hb_iter (o);
63
    if (iter.is_random_access_iterator)
64
      resize (hb_len (iter));
65
    hb_copy (iter, *this);
66
  }
67
68
  struct item_t
69
  {
70
    K key;
71
    uint32_t hash : 30;
72
    uint32_t is_used_ : 1;
73
    uint32_t is_tombstone_ : 1;
74
    V value;
75
76
    item_t () : key (),
77
    hash (0),
78
    is_used_ (false), is_tombstone_ (false),
79
3.16M
    value () {}
hb_hashmap_t<unsigned int, unsigned int, true>::item_t::item_t()
Line
Count
Source
79
3.05M
    value () {}
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::item_t()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::item_t()
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::item_t()
Line
Count
Source
79
115k
    value () {}
80
81
586k
    bool is_used () const { return is_used_; }
hb_hashmap_t<unsigned int, unsigned int, true>::item_t::is_used() const
Line
Count
Source
81
381k
    bool is_used () const { return is_used_; }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::is_used() const
Line
Count
Source
81
205k
    bool is_used () const { return is_used_; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_t::is_used() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_t::is_used() const
82
243k
    void set_used (bool is_used) { is_used_ = is_used; }
hb_hashmap_t<unsigned int, unsigned int, true>::item_t::set_used(bool)
Line
Count
Source
82
190k
    void set_used (bool is_used) { is_used_ = is_used; }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::set_used(bool)
Line
Count
Source
82
52.7k
    void set_used (bool is_used) { is_used_ = is_used; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::set_used(bool)
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_t::set_used(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::set_used(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_t::set_used(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::set_used(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::set_used(bool)
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_t::set_used(bool)
83
56.5k
    bool is_tombstone () const { return is_tombstone_; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::item_t::is_tombstone() const
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::is_tombstone() const
Line
Count
Source
83
56.5k
    bool is_tombstone () const { return is_tombstone_; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_t::is_tombstone() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_t::is_tombstone() const
84
243k
    void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
hb_hashmap_t<unsigned int, unsigned int, true>::item_t::set_tombstone(bool)
Line
Count
Source
84
190k
    void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::set_tombstone(bool)
Line
Count
Source
84
52.7k
    void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::set_tombstone(bool)
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_t::set_tombstone(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::set_tombstone(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_t::set_tombstone(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::set_tombstone(bool)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::set_tombstone(bool)
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_t::set_tombstone(bool)
85
75.0k
    bool is_real () const { return is_used_ && !is_tombstone_; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::item_t::is_real() const
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::is_real() const
Line
Count
Source
85
75.0k
    bool is_real () const { return is_used_ && !is_tombstone_; }
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::item_t::is_real() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_t::is_real() const
86
87
    template <bool v = minus_one,
88
        hb_enable_if (v == false)>
89
32.4k
    static inline const V& default_value () { return Null(V); };
unsigned int const& hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::default_value<false, (void*)0>()
Line
Count
Source
89
32.4k
    static inline const V& default_value () { return Null(V); };
Unexecuted instantiation: hb::unique_ptr<hb_set_t> const& hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::default_value<false, (void*)0>()
Unexecuted instantiation: int const& hb_hashmap_t<unsigned int, int, false>::item_t::default_value<false, (void*)0>()
Unexecuted instantiation: hb::shared_ptr<hb_set_t> const& hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::default_value<false, (void*)0>()
Unexecuted instantiation: hb_pair_t<unsigned int, int> const& hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::default_value<false, (void*)0>()
Unexecuted instantiation: float const& hb_hashmap_t<unsigned int, float, false>::item_t::default_value<false, (void*)0>()
Unexecuted instantiation: hb_array_t<char const> const& hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_t::default_value<false, (void*)0>()
90
    template <bool v = minus_one,
91
        hb_enable_if (v == true)>
92
    static inline const V& default_value ()
93
0
    {
94
0
      static_assert (hb_is_same (V, hb_codepoint_t), "");
95
0
      return minus_1;
96
0
    };
97
98
28.7k
    bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::item_t::operator==(unsigned int const&) const
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_t::operator==(hb_serialize_context_t::object_t const* const&) const
Line
Count
Source
98
28.7k
    bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_t::operator==(hb::shared_ptr<hb_map_t> const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::item_t::operator==(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_t::operator==(hb_ot_name_record_ids_t const&) const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_t::operator==(hb_ot_name_record_ids_t const&) const
99
    bool operator == (const item_t &o) const { return *this == o.key; }
100
0
    hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::item_t::get_pair() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_t::get_pair() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::item_t::get_pair() const
101
    hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); }
102
103
    uint32_t total_hash () const
104
0
    { return (hash * 31) + hb_hash (value); }
105
  };
106
107
  hb_object_header_t header;
108
  unsigned int successful : 1; /* Allocations successful */
109
  unsigned int population : 31; /* Not including tombstones. */
110
  unsigned int occupancy; /* Including tombstones. */
111
  unsigned int mask;
112
  unsigned int prime;
113
  item_t *items;
114
115
  friend void swap (hb_hashmap_t& a, hb_hashmap_t& b)
116
0
  {
117
0
    if (unlikely (!a.successful || !b.successful))
118
0
      return;
119
0
    unsigned tmp = a.population;
120
0
    a.population = b.population;
121
0
    b.population = tmp;
122
0
    //hb_swap (a.population, b.population);
123
0
    hb_swap (a.occupancy, b.occupancy);
124
0
    hb_swap (a.mask, b.mask);
125
0
    hb_swap (a.prime, b.prime);
126
0
    hb_swap (a.items, b.items);
127
0
  }
128
  void init ()
129
199k
  {
130
199k
    hb_object_init (this);
131
132
199k
    successful = true;
133
199k
    population = occupancy = 0;
134
199k
    mask = 0;
135
199k
    prime = 0;
136
199k
    items = nullptr;
137
199k
  }
hb_hashmap_t<unsigned int, unsigned int, true>::init()
Line
Count
Source
129
191k
  {
130
191k
    hb_object_init (this);
131
132
191k
    successful = true;
133
191k
    population = occupancy = 0;
134
191k
    mask = 0;
135
191k
    prime = 0;
136
191k
    items = nullptr;
137
191k
  }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::init()
Line
Count
Source
129
8.05k
  {
130
8.05k
    hb_object_init (this);
131
132
8.05k
    successful = true;
133
8.05k
    population = occupancy = 0;
134
8.05k
    mask = 0;
135
8.05k
    prime = 0;
136
8.05k
    items = nullptr;
137
8.05k
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_blob_t>, false>::init()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::init()
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::init()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::init()
138
  void fini ()
139
203k
  {
140
203k
    hb_object_fini (this);
141
142
203k
    if (likely (items)) {
143
193k
      unsigned size = mask + 1;
144
3.32M
      for (unsigned i = 0; i < size; i++)
145
3.13M
        items[i].~item_t ();
146
193k
      hb_free (items);
147
193k
      items = nullptr;
148
193k
    }
149
203k
    population = occupancy = 0;
150
203k
  }
hb_hashmap_t<unsigned int, unsigned int, true>::fini()
Line
Count
Source
139
191k
  {
140
191k
    hb_object_fini (this);
141
142
191k
    if (likely (items)) {
143
190k
      unsigned size = mask + 1;
144
3.24M
      for (unsigned i = 0; i < size; i++)
145
3.05M
        items[i].~item_t ();
146
190k
      hb_free (items);
147
190k
      items = nullptr;
148
190k
    }
149
191k
    population = occupancy = 0;
150
191k
  }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::fini()
Line
Count
Source
139
12.0k
  {
140
12.0k
    hb_object_fini (this);
141
142
12.0k
    if (likely (items)) {
143
3.26k
      unsigned size = mask + 1;
144
87.2k
      for (unsigned i = 0; i < size; i++)
145
84.0k
        items[i].~item_t ();
146
3.26k
      hb_free (items);
147
3.26k
      items = nullptr;
148
3.26k
    }
149
12.0k
    population = occupancy = 0;
150
12.0k
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::fini()
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_blob_t>, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::fini()
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::fini()
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::fini()
151
152
  void reset ()
153
0
  {
154
0
    successful = true;
155
0
    clear ();
156
0
  }
157
158
37.6k
  bool in_error () const { return !successful; }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::in_error() const
Line
Count
Source
158
37.6k
  bool in_error () const { return !successful; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::in_error() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::in_error() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::in_error() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_blob_t>, false>::in_error() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::in_error() const
159
160
  bool resize (unsigned new_population = 0)
161
196k
  {
162
196k
    if (unlikely (!successful)) return false;
163
164
196k
    if (new_population != 0 && (new_population + new_population / 2) < mask) return true;
165
166
196k
    unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8);
167
196k
    unsigned int new_size = 1u << power;
168
196k
    item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t));
169
196k
    if (unlikely (!new_items))
170
1.07k
    {
171
1.07k
      successful = false;
172
1.07k
      return false;
173
1.07k
    }
174
194k
    for (auto &_ : hb_iter (new_items, new_size))
175
3.16M
      new (&_) item_t ();
176
177
194k
    unsigned int old_size = size ();
178
194k
    item_t *old_items = items;
179
180
    /* Switch to new, empty, array. */
181
194k
    population = occupancy = 0;
182
194k
    mask = new_size - 1;
183
194k
    prime = prime_for (power);
184
194k
    items = new_items;
185
186
    /* Insert back old items. */
187
226k
    for (unsigned int i = 0; i < old_size; i++)
188
31.8k
    {
189
31.8k
      if (old_items[i].is_real ())
190
20.7k
      {
191
20.7k
  set_with_hash (std::move (old_items[i].key),
192
20.7k
           old_items[i].hash,
193
20.7k
           std::move (old_items[i].value));
194
20.7k
      }
195
31.8k
      old_items[i].~item_t ();
196
31.8k
    }
197
198
194k
    hb_free (old_items);
199
200
194k
    return true;
201
196k
  }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::resize(unsigned int)
Line
Count
Source
161
4.38k
  {
162
4.38k
    if (unlikely (!successful)) return false;
163
164
4.38k
    if (new_population != 0 && (new_population + new_population / 2) < mask) return true;
165
166
4.38k
    unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8);
167
4.38k
    unsigned int new_size = 1u << power;
168
4.38k
    item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t));
169
4.38k
    if (unlikely (!new_items))
170
192
    {
171
192
      successful = false;
172
192
      return false;
173
192
    }
174
4.19k
    for (auto &_ : hb_iter (new_items, new_size))
175
115k
      new (&_) item_t ();
176
177
4.19k
    unsigned int old_size = size ();
178
4.19k
    item_t *old_items = items;
179
180
    /* Switch to new, empty, array. */
181
4.19k
    population = occupancy = 0;
182
4.19k
    mask = new_size - 1;
183
4.19k
    prime = prime_for (power);
184
4.19k
    items = new_items;
185
186
    /* Insert back old items. */
187
36.0k
    for (unsigned int i = 0; i < old_size; i++)
188
31.8k
    {
189
31.8k
      if (old_items[i].is_real ())
190
20.7k
      {
191
20.7k
  set_with_hash (std::move (old_items[i].key),
192
20.7k
           old_items[i].hash,
193
20.7k
           std::move (old_items[i].value));
194
20.7k
      }
195
31.8k
      old_items[i].~item_t ();
196
31.8k
    }
197
198
4.19k
    hb_free (old_items);
199
200
4.19k
    return true;
201
4.38k
  }
hb_hashmap_t<unsigned int, unsigned int, true>::resize(unsigned int)
Line
Count
Source
161
191k
  {
162
191k
    if (unlikely (!successful)) return false;
163
164
191k
    if (new_population != 0 && (new_population + new_population / 2) < mask) return true;
165
166
191k
    unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8);
167
191k
    unsigned int new_size = 1u << power;
168
191k
    item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t));
169
191k
    if (unlikely (!new_items))
170
887
    {
171
887
      successful = false;
172
887
      return false;
173
887
    }
174
190k
    for (auto &_ : hb_iter (new_items, new_size))
175
3.05M
      new (&_) item_t ();
176
177
190k
    unsigned int old_size = size ();
178
190k
    item_t *old_items = items;
179
180
    /* Switch to new, empty, array. */
181
190k
    population = occupancy = 0;
182
190k
    mask = new_size - 1;
183
190k
    prime = prime_for (power);
184
190k
    items = new_items;
185
186
    /* Insert back old items. */
187
190k
    for (unsigned int i = 0; i < old_size; i++)
188
0
    {
189
0
      if (old_items[i].is_real ())
190
0
      {
191
0
  set_with_hash (std::move (old_items[i].key),
192
0
           old_items[i].hash,
193
0
           std::move (old_items[i].value));
194
0
      }
195
0
      old_items[i].~item_t ();
196
0
    }
197
198
190k
    hb_free (old_items);
199
200
190k
    return true;
201
191k
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::resize(unsigned int)
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::resize(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::resize(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::resize(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::resize(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::resize(unsigned int)
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::resize(unsigned int)
202
203
  template <typename KK, typename VV>
204
  bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false)
205
245k
  {
206
245k
    if (unlikely (!successful)) return false;
207
244k
    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
208
243k
    item_t &item = item_for_hash (key, hash);
209
210
243k
    if (is_delete && !(item == key))
211
0
      return true; /* Trying to delete non-existent key. */
212
213
243k
    if (item.is_used ())
214
0
    {
215
0
      occupancy--;
216
0
      if (!item.is_tombstone ())
217
0
  population--;
218
0
    }
219
220
243k
    item.key = std::forward<KK> (key);
221
243k
    item.value = std::forward<VV> (value);
222
243k
    item.hash = hash;
223
243k
    item.set_used (true);
224
243k
    item.set_tombstone (is_delete);
225
226
243k
    occupancy++;
227
243k
    if (!is_delete)
228
243k
      population++;
229
230
243k
    return true;
231
243k
  }
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, unsigned int const&>(unsigned int const&, unsigned int, unsigned int const&, bool)
bool hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::set_with_hash<hb_serialize_context_t::object_t*&, unsigned int&>(hb_serialize_context_t::object_t*&, unsigned int, unsigned int&, bool)
Line
Count
Source
205
32.2k
  {
206
32.2k
    if (unlikely (!successful)) return false;
207
32.2k
    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
208
32.0k
    item_t &item = item_for_hash (key, hash);
209
210
32.0k
    if (is_delete && !(item == key))
211
0
      return true; /* Trying to delete non-existent key. */
212
213
32.0k
    if (item.is_used ())
214
0
    {
215
0
      occupancy--;
216
0
      if (!item.is_tombstone ())
217
0
  population--;
218
0
    }
219
220
32.0k
    item.key = std::forward<KK> (key);
221
32.0k
    item.value = std::forward<VV> (value);
222
32.0k
    item.hash = hash;
223
32.0k
    item.set_used (true);
224
32.0k
    item.set_tombstone (is_delete);
225
226
32.0k
    occupancy++;
227
32.0k
    if (!is_delete)
228
32.0k
      population++;
229
230
32.0k
    return true;
231
32.0k
  }
bool hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::set_with_hash<hb_serialize_context_t::object_t const*, unsigned int>(hb_serialize_context_t::object_t const*&&, unsigned int, unsigned int&&, bool)
Line
Count
Source
205
20.7k
  {
206
20.7k
    if (unlikely (!successful)) return false;
207
20.7k
    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
208
20.7k
    item_t &item = item_for_hash (key, hash);
209
210
20.7k
    if (is_delete && !(item == key))
211
0
      return true; /* Trying to delete non-existent key. */
212
213
20.7k
    if (item.is_used ())
214
0
    {
215
0
      occupancy--;
216
0
      if (!item.is_tombstone ())
217
0
  population--;
218
0
    }
219
220
20.7k
    item.key = std::forward<KK> (key);
221
20.7k
    item.value = std::forward<VV> (value);
222
20.7k
    item.hash = hash;
223
20.7k
    item.set_used (true);
224
20.7k
    item.set_tombstone (is_delete);
225
226
20.7k
    occupancy++;
227
20.7k
    if (!is_delete)
228
20.7k
      population++;
229
230
20.7k
    return true;
231
20.7k
  }
Unexecuted instantiation: bool hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::set_with_hash<hb_serialize_context_t::object_t const* const&, unsigned int const&>(hb_serialize_context_t::object_t const* const&, unsigned int, unsigned int const&, bool)
bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, unsigned int&>(unsigned int const&, unsigned int, unsigned int&, bool)
Line
Count
Source
205
192k
  {
206
192k
    if (unlikely (!successful)) return false;
207
191k
    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
208
190k
    item_t &item = item_for_hash (key, hash);
209
210
190k
    if (is_delete && !(item == key))
211
0
      return true; /* Trying to delete non-existent key. */
212
213
190k
    if (item.is_used ())
214
0
    {
215
0
      occupancy--;
216
0
      if (!item.is_tombstone ())
217
0
  population--;
218
0
    }
219
220
190k
    item.key = std::forward<KK> (key);
221
190k
    item.value = std::forward<VV> (value);
222
190k
    item.hash = hash;
223
190k
    item.set_used (true);
224
190k
    item.set_tombstone (is_delete);
225
226
190k
    occupancy++;
227
190k
    if (!is_delete)
228
190k
      population++;
229
230
190k
    return true;
231
190k
  }
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int, unsigned int>(unsigned int&&, unsigned int, unsigned int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::set_with_hash<unsigned int const&, hb::unique_ptr<hb_set_t> >(unsigned int const&, unsigned int, hb::unique_ptr<hb_set_t>&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::set_with_hash<unsigned int, hb::unique_ptr<hb_set_t> >(unsigned int&&, unsigned int, hb::unique_ptr<hb_set_t>&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int, int>(unsigned int&&, unsigned int, int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int, unsigned int&>(unsigned int&&, unsigned int, unsigned int&, bool)
Unexecuted instantiation: bool hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::set_with_hash<hb::shared_ptr<hb_map_t> const&, int>(hb::shared_ptr<hb_map_t> const&, unsigned int, int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::set_with_hash<hb::shared_ptr<hb_map_t>, unsigned int>(hb::shared_ptr<hb_map_t>&&, unsigned int, unsigned int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::set_with_hash<unsigned int const&, hb::shared_ptr<hb_set_t>&>(unsigned int const&, unsigned int, hb::shared_ptr<hb_set_t>&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::set_with_hash<unsigned int, hb::shared_ptr<hb_set_t> >(unsigned int&&, unsigned int, hb::shared_ptr<hb_set_t>&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, OT::Feature const*, false>::set_with_hash<unsigned int, OT::Feature const*>(unsigned int&&, unsigned int, OT::Feature const*&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::set_with_hash<unsigned int, hb_pair_t<unsigned int, int> >(unsigned int&&, unsigned int, hb_pair_t<unsigned int, int>&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::set_with_hash<unsigned int const&, hb_pair_t<unsigned int, int> >(unsigned int const&, unsigned int, hb_pair_t<unsigned int, int>&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, unsigned int>(unsigned int const&, unsigned int, unsigned int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, bool&>(unsigned int const&, unsigned int, bool&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_set_t, false>::set_with_hash<unsigned int const&, hb_set_t>(unsigned int const&, unsigned int, hb_set_t&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_set_t, false>::set_with_hash<unsigned int, hb_set_t>(unsigned int&&, unsigned int, hb_set_t&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, OT::OffsetTo<OT::ClipBox, OT::IntType<unsigned int, 3u>, true> const&>(unsigned int const&, unsigned int, OT::OffsetTo<OT::ClipBox, OT::IntType<unsigned int, 3u>, true> const&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, int>(unsigned int const&, unsigned int, int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::set_with_hash<unsigned int const&, hb_pair_t<unsigned int, int&> >(unsigned int const&, unsigned int, hb_pair_t<unsigned int, int&>&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set_with_hash<unsigned int const&, OT::IntType<unsigned short, 2u> const&>(unsigned int const&, unsigned int, OT::IntType<unsigned short, 2u> const&, bool)
Unexecuted instantiation: bool hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::set_with_hash<hb_ot_name_record_ids_t const&, int>(hb_ot_name_record_ids_t const&, unsigned int, int&&, bool)
Unexecuted instantiation: bool hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::set_with_hash<hb_ot_name_record_ids_t, unsigned int>(hb_ot_name_record_ids_t&&, unsigned int, unsigned int&&, bool)
232
233
  template <typename VV>
234
192k
  bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<unsigned int const&>(unsigned int const&, unsigned int const&)
bool hb_hashmap_t<unsigned int, unsigned int, true>::set<unsigned int&>(unsigned int const&, unsigned int&)
Line
Count
Source
234
192k
  bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::set<hb::unique_ptr<hb_set_t> >(unsigned int const&, hb::unique_ptr<hb_set_t>&&)
Unexecuted instantiation: bool hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::set<int>(hb::shared_ptr<hb_map_t> const&, int&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::set<hb::shared_ptr<hb_set_t>&>(unsigned int const&, hb::shared_ptr<hb_set_t>&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::set<hb_pair_t<unsigned int, int> >(unsigned int const&, hb_pair_t<unsigned int, int>&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<unsigned int>(unsigned int const&, unsigned int&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<bool&>(unsigned int const&, bool&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_set_t, false>::set<hb_set_t>(unsigned int const&, hb_set_t&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<OT::OffsetTo<OT::ClipBox, OT::IntType<unsigned int, 3u>, true> const&>(unsigned int const&, OT::OffsetTo<OT::ClipBox, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<int>(unsigned int const&, int&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::set<hb_pair_t<unsigned int, int&> >(unsigned int const&, hb_pair_t<unsigned int, int&>&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<OT::IntType<unsigned short, 2u> const&>(unsigned int const&, OT::IntType<unsigned short, 2u> const&)
Unexecuted instantiation: bool hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::set<int>(hb_ot_name_record_ids_t const&, int&&)
235
  template <typename VV>
236
0
  bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); }
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<int>(unsigned int&&, int&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<unsigned int&>(unsigned int&&, unsigned int&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, OT::Feature const*, false>::set<OT::Feature const*>(unsigned int&&, OT::Feature const*&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::set<hb_pair_t<unsigned int, int> >(unsigned int&&, hb_pair_t<unsigned int, int>&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::set<hb::unique_ptr<hb_set_t> >(unsigned int&&, hb::unique_ptr<hb_set_t>&&)
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::set<unsigned int>(unsigned int&&, unsigned int&&)
237
238
  const V& get_with_hash (const K &key, uint32_t hash) const
239
46.8k
  {
240
46.8k
    if (unlikely (!items)) return item_t::default_value ();
241
43.2k
    auto &item = item_for_hash (key, hash);
242
43.2k
    return item.is_real () && item == key ? item.value : item_t::default_value ();
243
46.8k
  }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::get_with_hash(hb_serialize_context_t::object_t const* const&, unsigned int) const
Line
Count
Source
239
46.8k
  {
240
46.8k
    if (unlikely (!items)) return item_t::default_value ();
241
43.2k
    auto &item = item_for_hash (key, hash);
242
43.2k
    return item.is_real () && item == key ? item.value : item_t::default_value ();
243
46.8k
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::get_with_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::get_with_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::get_with_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::get_with_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::get_with_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::get_with_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::get_with_hash(hb_ot_name_record_ids_t const&, unsigned int) const
244
  const V& get (const K &key) const
245
0
  {
246
0
    if (unlikely (!items)) return item_t::default_value ();
247
0
    return get_with_hash (key, hb_hash (key));
248
0
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::get(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::get(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::get(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::get(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::get(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::get(unsigned int const&) const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::get(hb_ot_name_record_ids_t const&) const
249
250
0
  void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
Unexecuted instantiation: hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::del(hb_serialize_context_t::object_t const* const&)
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::del(unsigned int const&)
251
252
  /* Has interface. */
253
0
  const V& operator [] (K k) const { return get (k); }
254
  template <typename VV=V>
255
  bool has (K key, VV **vp = nullptr) const
256
0
  {
257
0
    if (unlikely (!items))
258
0
      return false;
259
0
    auto &item = item_for_hash (key, hb_hash (key));
260
0
    if (item.is_real () && item == key)
261
0
    {
262
0
      if (vp) *vp = std::addressof (item.value);
263
0
      return true;
264
0
    }
265
0
    else
266
0
      return false;
267
0
  }
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::has<unsigned int>(unsigned int, unsigned int**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, unsigned int, true>::has<unsigned int const>(unsigned int, unsigned int const**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, OT::Feature const*, false>::has<OT::Feature const*>(unsigned int, OT::Feature const***) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::has<hb::unique_ptr<hb_set_t> >(unsigned int, hb::unique_ptr<hb_set_t>**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, int, false>::has<int>(unsigned int, int**) const
Unexecuted instantiation: bool hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::has<unsigned int>(hb::shared_ptr<hb_map_t>, unsigned int**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::has<hb::shared_ptr<hb_set_t> >(unsigned int, hb::shared_ptr<hb_set_t>**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::has<hb_pair_t<unsigned int, int> >(unsigned int, hb_pair_t<unsigned int, int>**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, hb_set_t, false>::has<hb_set_t>(unsigned int, hb_set_t**) const
Unexecuted instantiation: bool hb_hashmap_t<unsigned int, float, false>::has<float>(unsigned int, float**) const
Unexecuted instantiation: bool hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::has<hb_array_t<char const> >(hb_ot_name_record_ids_t, hb_array_t<char const>**) const
Unexecuted instantiation: bool hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::has<unsigned int>(hb_ot_name_record_ids_t, unsigned int**) const
268
  /* Projection. */
269
  V operator () (K k) const { return get (k); }
270
271
194k
  unsigned size () const { return mask ? mask + 1 : 0; }
hb_hashmap_t<unsigned int, unsigned int, true>::size() const
Line
Count
Source
271
190k
  unsigned size () const { return mask ? mask + 1 : 0; }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::size() const
Line
Count
Source
271
4.19k
  unsigned size () const { return mask ? mask + 1 : 0; }
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::size() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::size() const
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::size() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::size() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::size() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::size() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::size() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::size() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::size() const
272
273
  void clear ()
274
0
  {
275
0
    if (unlikely (!successful)) return;
276
277
0
    for (auto &_ : hb_iter (items, size ()))
278
0
    {
279
      /* Reconstruct items. */
280
0
      _.~item_t ();
281
0
      new (&_) item_t ();
282
0
    }
283
284
0
    population = occupancy = 0;
285
0
  }
286
287
0
  bool is_empty () const { return population == 0; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::is_empty() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::is_empty() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::is_empty() const
288
  explicit operator bool () const { return !is_empty (); }
289
290
  uint32_t hash () const
291
0
  {
292
0
    return
293
0
    + iter_items ()
294
0
    | hb_reduce ([] (uint32_t h, const item_t &_) { return h ^ _.total_hash (); }, (uint32_t) 0u)
295
0
    ;
296
0
  }
297
298
  bool is_equal (const hb_hashmap_t &other) const
299
0
  {
300
0
    if (population != other.population) return false;
301
302
0
    for (auto pair : iter ())
303
0
      if (other.get (pair.first) != pair.second)
304
0
        return false;
305
306
0
    return true;
307
0
  }
308
0
  bool operator == (const hb_hashmap_t &other) const { return is_equal (other); }
309
  bool operator != (const hb_hashmap_t &other) const { return !is_equal (other); }
310
311
0
  unsigned int get_population () const { return population; }
Unexecuted instantiation: hb_hashmap_t<unsigned int, unsigned int, true>::get_population() const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::get_population() const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::get_population() const
312
313
  void update (const hb_hashmap_t &other)
314
0
  {
315
0
    if (unlikely (!successful)) return;
316
317
0
    hb_copy (other, *this);
318
0
  }
319
320
  void keys (hb_set_t &keys_) const
321
0
  {
322
0
    hb_copy (keys() , keys_);
323
0
  }
324
325
  void values (hb_set_t &values_) const
326
0
  {
327
0
    hb_copy (values() , values_);
328
0
  }
329
330
  /*
331
   * Iterator
332
   */
333
334
  auto iter_items () const HB_AUTO_RETURN
335
  (
336
    + hb_iter (items, size ())
337
    | hb_filter (&item_t::is_real)
338
  )
339
  auto iter_ref () const HB_AUTO_RETURN
340
  (
341
    + iter_items ()
342
    | hb_map (&item_t::get_pair_ref)
343
  )
344
  auto iter () const HB_AUTO_RETURN
345
  (
346
    + iter_items ()
347
    | hb_map (&item_t::get_pair)
348
  )
349
  auto keys_ref () const HB_AUTO_RETURN
350
  (
351
    + iter_items ()
352
    | hb_map (&item_t::key)
353
  )
354
  auto keys () const HB_AUTO_RETURN
355
  (
356
    + keys_ref ()
357
    | hb_map (hb_ridentity)
358
  )
359
  auto values_ref () const HB_AUTO_RETURN
360
  (
361
    + iter_items ()
362
    | hb_map (&item_t::value)
363
  )
364
  auto values () const HB_AUTO_RETURN
365
  (
366
    + values_ref ()
367
    | hb_map (hb_ridentity)
368
  )
369
370
  /* C iterator. */
371
  bool next (int *idx,
372
       K *key,
373
       V *value) const
374
0
  {
375
0
    unsigned i = (unsigned) (*idx + 1);
376
377
0
    unsigned count = size ();
378
0
    while (i < count && !items[i].is_real ())
379
0
      i++;
380
381
0
    if (i >= count)
382
0
    {
383
0
      *idx = -1;
384
0
      return false;
385
0
    }
386
387
0
    *key = items[i].key;
388
0
    *value = items[i].value;
389
390
0
    *idx = (signed) i;
391
0
    return true;
392
0
  }
393
394
  /* Sink interface. */
395
  hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
396
0
  { set (v.first, v.second); return *this; }
397
  hb_hashmap_t& operator << (const hb_pair_t<K, V&&>& v)
398
  { set (v.first, std::move (v.second)); return *this; }
399
  hb_hashmap_t& operator << (const hb_pair_t<K&&, V>& v)
400
  { set (std::move (v.first), v.second); return *this; }
401
  hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v)
402
  { set (std::move (v.first), std::move (v.second)); return *this; }
403
404
  item_t& item_for_hash (const K &key, uint32_t hash) const
405
286k
  {
406
286k
    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
407
286k
    unsigned int i = hash % prime;
408
286k
    unsigned int step = 0;
409
286k
    unsigned int tombstone = (unsigned) -1;
410
343k
    while (items[i].is_used ())
411
70.8k
    {
412
70.8k
      if (items[i].hash == hash && items[i] == key)
413
14.3k
  return items[i];
414
56.5k
      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
415
0
  tombstone = i;
416
56.5k
      i = (i + ++step) & mask;
417
56.5k
    }
418
272k
    return items[tombstone == (unsigned) -1 ? i : tombstone];
419
286k
  }
hb_hashmap_t<unsigned int, unsigned int, true>::item_for_hash(unsigned int const&, unsigned int) const
Line
Count
Source
405
190k
  {
406
190k
    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
407
190k
    unsigned int i = hash % prime;
408
190k
    unsigned int step = 0;
409
190k
    unsigned int tombstone = (unsigned) -1;
410
190k
    while (items[i].is_used ())
411
0
    {
412
0
      if (items[i].hash == hash && items[i] == key)
413
0
  return items[i];
414
0
      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
415
0
  tombstone = i;
416
0
      i = (i + ++step) & mask;
417
0
    }
418
190k
    return items[tombstone == (unsigned) -1 ? i : tombstone];
419
190k
  }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::item_for_hash(hb_serialize_context_t::object_t const* const&, unsigned int) const
Line
Count
Source
405
95.9k
  {
406
95.9k
    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
407
95.9k
    unsigned int i = hash % prime;
408
95.9k
    unsigned int step = 0;
409
95.9k
    unsigned int tombstone = (unsigned) -1;
410
152k
    while (items[i].is_used ())
411
70.8k
    {
412
70.8k
      if (items[i].hash == hash && items[i] == key)
413
14.3k
  return items[i];
414
56.5k
      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
415
0
  tombstone = i;
416
56.5k
      i = (i + ++step) & mask;
417
56.5k
    }
418
81.5k
    return items[tombstone == (unsigned) -1 ? i : tombstone];
419
95.9k
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, int, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::item_for_hash(hb::shared_ptr<hb_map_t> const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<unsigned int, float, false>::item_for_hash(unsigned int const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, hb_array_t<char const>, false>::item_for_hash(hb_ot_name_record_ids_t const&, unsigned int) const
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::item_for_hash(hb_ot_name_record_ids_t const&, unsigned int) const
420
421
  static unsigned int prime_for (unsigned int shift)
422
194k
  {
423
    /* Following comment and table copied from glib. */
424
    /* Each table size has an associated prime modulo (the first prime
425
     * lower than the table size) used to find the initial bucket. Probing
426
     * then works modulo 2^n. The prime modulo is necessary to get a
427
     * good distribution with poor hash functions.
428
     */
429
    /* Not declaring static to make all kinds of compilers happy... */
430
194k
    /*static*/ const unsigned int prime_mod [32] =
431
194k
    {
432
194k
      1,          /* For 1 << 0 */
433
194k
      2,
434
194k
      3,
435
194k
      7,
436
194k
      13,
437
194k
      31,
438
194k
      61,
439
194k
      127,
440
194k
      251,
441
194k
      509,
442
194k
      1021,
443
194k
      2039,
444
194k
      4093,
445
194k
      8191,
446
194k
      16381,
447
194k
      32749,
448
194k
      65521,      /* For 1 << 16 */
449
194k
      131071,
450
194k
      262139,
451
194k
      524287,
452
194k
      1048573,
453
194k
      2097143,
454
194k
      4194301,
455
194k
      8388593,
456
194k
      16777213,
457
194k
      33554393,
458
194k
      67108859,
459
194k
      134217689,
460
194k
      268435399,
461
194k
      536870909,
462
194k
      1073741789,
463
194k
      2147483647  /* For 1 << 31 */
464
194k
    };
465
466
194k
    if (unlikely (shift >= ARRAY_LENGTH (prime_mod)))
467
0
      return prime_mod[ARRAY_LENGTH (prime_mod) - 1];
468
469
194k
    return prime_mod[shift];
470
194k
  }
hb_hashmap_t<hb_serialize_context_t::object_t const*, unsigned int, false>::prime_for(unsigned int)
Line
Count
Source
422
4.19k
  {
423
    /* Following comment and table copied from glib. */
424
    /* Each table size has an associated prime modulo (the first prime
425
     * lower than the table size) used to find the initial bucket. Probing
426
     * then works modulo 2^n. The prime modulo is necessary to get a
427
     * good distribution with poor hash functions.
428
     */
429
    /* Not declaring static to make all kinds of compilers happy... */
430
4.19k
    /*static*/ const unsigned int prime_mod [32] =
431
4.19k
    {
432
4.19k
      1,          /* For 1 << 0 */
433
4.19k
      2,
434
4.19k
      3,
435
4.19k
      7,
436
4.19k
      13,
437
4.19k
      31,
438
4.19k
      61,
439
4.19k
      127,
440
4.19k
      251,
441
4.19k
      509,
442
4.19k
      1021,
443
4.19k
      2039,
444
4.19k
      4093,
445
4.19k
      8191,
446
4.19k
      16381,
447
4.19k
      32749,
448
4.19k
      65521,      /* For 1 << 16 */
449
4.19k
      131071,
450
4.19k
      262139,
451
4.19k
      524287,
452
4.19k
      1048573,
453
4.19k
      2097143,
454
4.19k
      4194301,
455
4.19k
      8388593,
456
4.19k
      16777213,
457
4.19k
      33554393,
458
4.19k
      67108859,
459
4.19k
      134217689,
460
4.19k
      268435399,
461
4.19k
      536870909,
462
4.19k
      1073741789,
463
4.19k
      2147483647  /* For 1 << 31 */
464
4.19k
    };
465
466
4.19k
    if (unlikely (shift >= ARRAY_LENGTH (prime_mod)))
467
0
      return prime_mod[ARRAY_LENGTH (prime_mod) - 1];
468
469
4.19k
    return prime_mod[shift];
470
4.19k
  }
hb_hashmap_t<unsigned int, unsigned int, true>::prime_for(unsigned int)
Line
Count
Source
422
190k
  {
423
    /* Following comment and table copied from glib. */
424
    /* Each table size has an associated prime modulo (the first prime
425
     * lower than the table size) used to find the initial bucket. Probing
426
     * then works modulo 2^n. The prime modulo is necessary to get a
427
     * good distribution with poor hash functions.
428
     */
429
    /* Not declaring static to make all kinds of compilers happy... */
430
190k
    /*static*/ const unsigned int prime_mod [32] =
431
190k
    {
432
190k
      1,          /* For 1 << 0 */
433
190k
      2,
434
190k
      3,
435
190k
      7,
436
190k
      13,
437
190k
      31,
438
190k
      61,
439
190k
      127,
440
190k
      251,
441
190k
      509,
442
190k
      1021,
443
190k
      2039,
444
190k
      4093,
445
190k
      8191,
446
190k
      16381,
447
190k
      32749,
448
190k
      65521,      /* For 1 << 16 */
449
190k
      131071,
450
190k
      262139,
451
190k
      524287,
452
190k
      1048573,
453
190k
      2097143,
454
190k
      4194301,
455
190k
      8388593,
456
190k
      16777213,
457
190k
      33554393,
458
190k
      67108859,
459
190k
      134217689,
460
190k
      268435399,
461
190k
      536870909,
462
190k
      1073741789,
463
190k
      2147483647  /* For 1 << 31 */
464
190k
    };
465
466
190k
    if (unlikely (shift >= ARRAY_LENGTH (prime_mod)))
467
0
      return prime_mod[ARRAY_LENGTH (prime_mod) - 1];
468
469
190k
    return prime_mod[shift];
470
190k
  }
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::unique_ptr<hb_set_t>, false>::prime_for(unsigned int)
Unexecuted instantiation: hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned int, false>::prime_for(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb::shared_ptr<hb_set_t>, false>::prime_for(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, OT::Feature const*, false>::prime_for(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_pair_t<unsigned int, int>, false>::prime_for(unsigned int)
Unexecuted instantiation: hb_hashmap_t<unsigned int, hb_set_t, false>::prime_for(unsigned int)
Unexecuted instantiation: hb_hashmap_t<hb_ot_name_record_ids_t, unsigned int, false>::prime_for(unsigned int)
471
};
472
473
/*
474
 * hb_map_t
475
 */
476
477
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
478
             hb_codepoint_t,
479
             true>
480
{
481
  using hashmap = hb_hashmap_t<hb_codepoint_t,
482
             hb_codepoint_t,
483
             true>;
484
485
  ~hb_map_t () = default;
486
191k
  hb_map_t () : hashmap () {}
487
0
  hb_map_t (const hb_map_t &o) : hashmap ((hashmap &) o) {}
488
0
  hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {}
489
0
  hb_map_t& operator= (const hb_map_t&) = default;
490
  hb_map_t& operator= (hb_map_t&&) = default;
491
0
  hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
492
  template <typename Iterable,
493
      hb_requires (hb_is_iterable (Iterable))>
494
  hb_map_t (const Iterable &o) : hashmap (o) {}
495
};
496
497
498
#endif /* HB_MAP_HH */