Coverage Report

Created: 2023-05-06 06:56

/src/harfbuzz/src/hb-set-digest.hh
Line
Count
Source
1
/*
2
 * Copyright © 2012  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_SET_DIGEST_HH
28
#define HB_SET_DIGEST_HH
29
30
#include "hb.hh"
31
#include "hb-machinery.hh"
32
33
/*
34
 * The set-digests here implement various "filters" that support
35
 * "approximate member query".  Conceptually these are like Bloom
36
 * Filter and Quotient Filter, however, much smaller, faster, and
37
 * designed to fit the requirements of our uses for glyph coverage
38
 * queries.
39
 *
40
 * Our filters are highly accurate if the lookup covers fairly local
41
 * set of glyphs, but fully flooded and ineffective if coverage is
42
 * all over the place.
43
 *
44
 * The way these are used is that the filter is first populated by
45
 * a lookup's or subtable's Coverage table(s), and then when we
46
 * want to apply the lookup or subtable to a glyph, before trying
47
 * to apply, we ask the filter if the glyph may be covered. If it's
48
 * not, we return early.
49
 *
50
 * We use these filters both at the lookup-level, and then again,
51
 * at the subtable-level. Both have performance win.
52
 *
53
 * The main filter we use is a combination of three bits-pattern
54
 * filters. A bits-pattern filter checks a number of bits (5 or 6)
55
 * of the input number (glyph-id in this case) and checks whether
56
 * its pattern is amongst the patterns of any of the accepted values.
57
 * The accepted patterns are represented as a "long" integer. The
58
 * check is done using four bitwise operations only.
59
 */
60
61
template <typename mask_t, unsigned int shift>
62
struct hb_set_digest_bits_pattern_t
63
{
64
  static constexpr unsigned mask_bytes = sizeof (mask_t);
65
  static constexpr unsigned mask_bits = sizeof (mask_t) * 8;
66
  static constexpr unsigned num_bits = 0
67
             + (mask_bytes >= 1 ? 3 : 0)
68
             + (mask_bytes >= 2 ? 1 : 0)
69
             + (mask_bytes >= 4 ? 1 : 0)
70
             + (mask_bytes >= 8 ? 1 : 0)
71
             + (mask_bytes >= 16? 1 : 0)
72
             + 0;
73
74
  static_assert ((shift < sizeof (hb_codepoint_t) * 8), "");
75
  static_assert ((shift + num_bits <= sizeof (hb_codepoint_t) * 8), "");
76
77
1.89M
  void init () { mask = 0; }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::init()
Line
Count
Source
77
631k
  void init () { mask = 0; }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::init()
Line
Count
Source
77
631k
  void init () { mask = 0; }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::init()
Line
Count
Source
77
631k
  void init () { mask = 0; }
78
79
171k
  void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::add(hb_set_digest_bits_pattern_t<unsigned long, 4u> const&)
Line
Count
Source
79
57.1k
  void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::add(hb_set_digest_bits_pattern_t<unsigned long, 0u> const&)
Line
Count
Source
79
57.1k
  void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::add(hb_set_digest_bits_pattern_t<unsigned long, 9u> const&)
Line
Count
Source
79
57.1k
  void add (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; }
80
81
22.6M
  void add (hb_codepoint_t g) { mask |= mask_for (g); }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::add(unsigned int)
Line
Count
Source
81
7.55M
  void add (hb_codepoint_t g) { mask |= mask_for (g); }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::add(unsigned int)
Line
Count
Source
81
7.55M
  void add (hb_codepoint_t g) { mask |= mask_for (g); }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::add(unsigned int)
Line
Count
Source
81
7.55M
  void add (hb_codepoint_t g) { mask |= mask_for (g); }
82
83
  bool add_range (hb_codepoint_t a, hb_codepoint_t b)
84
3.20M
  {
85
3.20M
    if ((b >> shift) - (a >> shift) >= mask_bits - 1)
86
1.70M
      mask = (mask_t) -1;
87
1.50M
    else {
88
1.50M
      mask_t ma = mask_for (a);
89
1.50M
      mask_t mb = mask_for (b);
90
1.50M
      mask |= mb + (mb - ma) - (mb < ma);
91
1.50M
    }
92
3.20M
    return true;
93
3.20M
  }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::add_range(unsigned int, unsigned int)
Line
Count
Source
84
1.06M
  {
85
1.06M
    if ((b >> shift) - (a >> shift) >= mask_bits - 1)
86
603k
      mask = (mask_t) -1;
87
465k
    else {
88
465k
      mask_t ma = mask_for (a);
89
465k
      mask_t mb = mask_for (b);
90
465k
      mask |= mb + (mb - ma) - (mb < ma);
91
465k
    }
92
1.06M
    return true;
93
1.06M
  }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::add_range(unsigned int, unsigned int)
Line
Count
Source
84
1.06M
  {
85
1.06M
    if ((b >> shift) - (a >> shift) >= mask_bits - 1)
86
694k
      mask = (mask_t) -1;
87
373k
    else {
88
373k
      mask_t ma = mask_for (a);
89
373k
      mask_t mb = mask_for (b);
90
373k
      mask |= mb + (mb - ma) - (mb < ma);
91
373k
    }
92
1.06M
    return true;
93
1.06M
  }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::add_range(unsigned int, unsigned int)
Line
Count
Source
84
1.06M
  {
85
1.06M
    if ((b >> shift) - (a >> shift) >= mask_bits - 1)
86
402k
      mask = (mask_t) -1;
87
666k
    else {
88
666k
      mask_t ma = mask_for (a);
89
666k
      mask_t mb = mask_for (b);
90
666k
      mask |= mb + (mb - ma) - (mb < ma);
91
666k
    }
92
1.06M
    return true;
93
1.06M
  }
94
95
  template <typename T>
96
  void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
97
1.21M
  {
98
10.5M
    for (unsigned int i = 0; i < count; i++)
99
9.29M
    {
100
9.29M
      add (*array);
101
9.29M
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
9.29M
    }
103
1.21M
  }
void hb_set_digest_bits_pattern_t<unsigned long, 4u>::add_array<unsigned int>(unsigned int const*, unsigned int, unsigned int)
Line
Count
Source
97
397k
  {
98
2.72M
    for (unsigned int i = 0; i < count; i++)
99
2.32M
    {
100
2.32M
      add (*array);
101
2.32M
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
2.32M
    }
103
397k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 0u>::add_array<unsigned int>(unsigned int const*, unsigned int, unsigned int)
Line
Count
Source
97
397k
  {
98
2.72M
    for (unsigned int i = 0; i < count; i++)
99
2.32M
    {
100
2.32M
      add (*array);
101
2.32M
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
2.32M
    }
103
397k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 9u>::add_array<unsigned int>(unsigned int const*, unsigned int, unsigned int)
Line
Count
Source
97
397k
  {
98
2.72M
    for (unsigned int i = 0; i < count; i++)
99
2.32M
    {
100
2.32M
      add (*array);
101
2.32M
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
2.32M
    }
103
397k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 4u>::add_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
97
6.15k
  {
98
623k
    for (unsigned int i = 0; i < count; i++)
99
617k
    {
100
617k
      add (*array);
101
617k
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
617k
    }
103
6.15k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 0u>::add_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
97
6.15k
  {
98
623k
    for (unsigned int i = 0; i < count; i++)
99
617k
    {
100
617k
      add (*array);
101
617k
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
617k
    }
103
6.15k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 9u>::add_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
97
6.15k
  {
98
623k
    for (unsigned int i = 0; i < count; i++)
99
617k
    {
100
617k
      add (*array);
101
617k
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
617k
    }
103
6.15k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 4u>::add_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
97
1.11k
  {
98
156k
    for (unsigned int i = 0; i < count; i++)
99
155k
    {
100
155k
      add (*array);
101
155k
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
155k
    }
103
1.11k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 0u>::add_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
97
1.11k
  {
98
156k
    for (unsigned int i = 0; i < count; i++)
99
155k
    {
100
155k
      add (*array);
101
155k
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
155k
    }
103
1.11k
  }
void hb_set_digest_bits_pattern_t<unsigned long, 9u>::add_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
97
1.11k
  {
98
156k
    for (unsigned int i = 0; i < count; i++)
99
155k
    {
100
155k
      add (*array);
101
155k
      array = &StructAtOffsetUnaligned<T> ((const void *) array, stride);
102
155k
    }
103
1.11k
  }
104
  template <typename T>
105
  void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
106
  template <typename T>
107
  bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
108
21.7k
  {
109
21.7k
    add_array (array, count, stride);
110
21.7k
    return true;
111
21.7k
  }
bool hb_set_digest_bits_pattern_t<unsigned long, 4u>::add_sorted_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
108
6.15k
  {
109
6.15k
    add_array (array, count, stride);
110
6.15k
    return true;
111
6.15k
  }
bool hb_set_digest_bits_pattern_t<unsigned long, 0u>::add_sorted_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
108
6.15k
  {
109
6.15k
    add_array (array, count, stride);
110
6.15k
    return true;
111
6.15k
  }
bool hb_set_digest_bits_pattern_t<unsigned long, 9u>::add_sorted_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
108
6.15k
  {
109
6.15k
    add_array (array, count, stride);
110
6.15k
    return true;
111
6.15k
  }
bool hb_set_digest_bits_pattern_t<unsigned long, 4u>::add_sorted_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
108
1.11k
  {
109
1.11k
    add_array (array, count, stride);
110
1.11k
    return true;
111
1.11k
  }
bool hb_set_digest_bits_pattern_t<unsigned long, 0u>::add_sorted_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
108
1.11k
  {
109
1.11k
    add_array (array, count, stride);
110
1.11k
    return true;
111
1.11k
  }
bool hb_set_digest_bits_pattern_t<unsigned long, 9u>::add_sorted_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
108
1.11k
  {
109
1.11k
    add_array (array, count, stride);
110
1.11k
    return true;
111
1.11k
  }
112
  template <typename T>
113
  bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
114
115
  bool may_have (const hb_set_digest_bits_pattern_t &o) const
116
830k
  { return mask & o.mask; }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::may_have(hb_set_digest_bits_pattern_t<unsigned long, 4u> const&) const
Line
Count
Source
116
774k
  { return mask & o.mask; }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::may_have(hb_set_digest_bits_pattern_t<unsigned long, 0u> const&) const
Line
Count
Source
116
29.6k
  { return mask & o.mask; }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::may_have(hb_set_digest_bits_pattern_t<unsigned long, 9u> const&) const
Line
Count
Source
116
25.7k
  { return mask & o.mask; }
117
118
  bool may_have (hb_codepoint_t g) const
119
25.1M
  { return mask & mask_for (g); }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::may_have(unsigned int) const
Line
Count
Source
119
8.49M
  { return mask & mask_for (g); }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::may_have(unsigned int) const
Line
Count
Source
119
8.36M
  { return mask & mask_for (g); }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::may_have(unsigned int) const
Line
Count
Source
119
8.31M
  { return mask & mask_for (g); }
120
121
  private:
122
123
  static mask_t mask_for (hb_codepoint_t g)
124
50.8M
  { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); }
hb_set_digest_bits_pattern_t<unsigned long, 4u>::mask_for(unsigned int)
Line
Count
Source
124
16.9M
  { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); }
hb_set_digest_bits_pattern_t<unsigned long, 0u>::mask_for(unsigned int)
Line
Count
Source
124
16.6M
  { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); }
hb_set_digest_bits_pattern_t<unsigned long, 9u>::mask_for(unsigned int)
Line
Count
Source
124
17.2M
  { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); }
125
  mask_t mask;
126
};
127
128
template <typename head_t, typename tail_t>
129
struct hb_set_digest_combiner_t
130
{
131
  void init ()
132
1.26M
  {
133
1.26M
    head.init ();
134
1.26M
    tail.init ();
135
1.26M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::init()
Line
Count
Source
132
631k
  {
133
631k
    head.init ();
134
631k
    tail.init ();
135
631k
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::init()
Line
Count
Source
132
631k
  {
133
631k
    head.init ();
134
631k
    tail.init ();
135
631k
  }
136
137
  void add (const hb_set_digest_combiner_t &o)
138
114k
  {
139
114k
    head.add (o.head);
140
114k
    tail.add (o.tail);
141
114k
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add(hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > > const&)
Line
Count
Source
138
57.1k
  {
139
57.1k
    head.add (o.head);
140
57.1k
    tail.add (o.tail);
141
57.1k
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::add(hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > const&)
Line
Count
Source
138
57.1k
  {
139
57.1k
    head.add (o.head);
140
57.1k
    tail.add (o.tail);
141
57.1k
  }
142
143
  void add (hb_codepoint_t g)
144
8.91M
  {
145
8.91M
    head.add (g);
146
8.91M
    tail.add (g);
147
8.91M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add(unsigned int)
Line
Count
Source
144
4.45M
  {
145
4.45M
    head.add (g);
146
4.45M
    tail.add (g);
147
4.45M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::add(unsigned int)
Line
Count
Source
144
4.45M
  {
145
4.45M
    head.add (g);
146
4.45M
    tail.add (g);
147
4.45M
  }
148
149
  bool add_range (hb_codepoint_t a, hb_codepoint_t b)
150
2.13M
  {
151
2.13M
    return head.add_range (a, b) &&
152
2.13M
     tail.add_range (a, b);
153
2.13M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add_range(unsigned int, unsigned int)
Line
Count
Source
150
1.06M
  {
151
1.06M
    return head.add_range (a, b) &&
152
1.06M
     tail.add_range (a, b);
153
1.06M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::add_range(unsigned int, unsigned int)
Line
Count
Source
150
1.06M
  {
151
1.06M
    return head.add_range (a, b) &&
152
1.06M
     tail.add_range (a, b);
153
1.06M
  }
154
  template <typename T>
155
  void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
156
795k
  {
157
795k
    head.add_array (array, count, stride);
158
795k
    tail.add_array (array, count, stride);
159
795k
  }
void hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add_array<unsigned int>(unsigned int const*, unsigned int, unsigned int)
Line
Count
Source
156
397k
  {
157
397k
    head.add_array (array, count, stride);
158
397k
    tail.add_array (array, count, stride);
159
397k
  }
void hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::add_array<unsigned int>(unsigned int const*, unsigned int, unsigned int)
Line
Count
Source
156
397k
  {
157
397k
    head.add_array (array, count, stride);
158
397k
    tail.add_array (array, count, stride);
159
397k
  }
160
  template <typename T>
161
  void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); }
162
  template <typename T>
163
  bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
164
14.5k
  {
165
14.5k
    return head.add_sorted_array (array, count, stride) &&
166
14.5k
     tail.add_sorted_array (array, count, stride);
167
14.5k
  }
bool hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add_sorted_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
164
6.15k
  {
165
6.15k
    return head.add_sorted_array (array, count, stride) &&
166
6.15k
     tail.add_sorted_array (array, count, stride);
167
6.15k
  }
bool hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::add_sorted_array<OT::HBGlyphID16>(OT::HBGlyphID16 const*, unsigned int, unsigned int)
Line
Count
Source
164
6.15k
  {
165
6.15k
    return head.add_sorted_array (array, count, stride) &&
166
6.15k
     tail.add_sorted_array (array, count, stride);
167
6.15k
  }
bool hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add_sorted_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
164
1.11k
  {
165
1.11k
    return head.add_sorted_array (array, count, stride) &&
166
1.11k
     tail.add_sorted_array (array, count, stride);
167
1.11k
  }
bool hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::add_sorted_array<OT::HBGlyphID24>(OT::HBGlyphID24 const*, unsigned int, unsigned int)
Line
Count
Source
164
1.11k
  {
165
1.11k
    return head.add_sorted_array (array, count, stride) &&
166
1.11k
     tail.add_sorted_array (array, count, stride);
167
1.11k
  }
168
  template <typename T>
169
7.26k
  bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
bool hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add_sorted_array<OT::HBGlyphID16>(hb_sorted_array_t<OT::HBGlyphID16 const> const&)
Line
Count
Source
169
6.15k
  bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
bool hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::add_sorted_array<OT::HBGlyphID24>(hb_sorted_array_t<OT::HBGlyphID24 const> const&)
Line
Count
Source
169
1.11k
  bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
170
171
  bool may_have (const hb_set_digest_combiner_t &o) const
172
804k
  {
173
804k
    return head.may_have (o.head) && tail.may_have (o.tail);
174
804k
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::may_have(hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > > const&) const
Line
Count
Source
172
774k
  {
173
774k
    return head.may_have (o.head) && tail.may_have (o.tail);
174
774k
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::may_have(hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > const&) const
Line
Count
Source
172
29.6k
  {
173
29.6k
    return head.may_have (o.head) && tail.may_have (o.tail);
174
29.6k
  }
175
176
  bool may_have (hb_codepoint_t g) const
177
16.8M
  {
178
16.8M
    return head.may_have (g) && tail.may_have (g);
179
16.8M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 4u>, hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> > >::may_have(unsigned int) const
Line
Count
Source
177
8.49M
  {
178
8.49M
    return head.may_have (g) && tail.may_have (g);
179
8.49M
  }
hb_set_digest_combiner_t<hb_set_digest_bits_pattern_t<unsigned long, 0u>, hb_set_digest_bits_pattern_t<unsigned long, 9u> >::may_have(unsigned int) const
Line
Count
Source
177
8.36M
  {
178
8.36M
    return head.may_have (g) && tail.may_have (g);
179
8.36M
  }
180
181
  private:
182
  head_t head;
183
  tail_t tail;
184
};
185
186
187
/*
188
 * hb_set_digest_t
189
 *
190
 * This is a combination of digests that performs "best".
191
 * There is not much science to this: it's a result of intuition
192
 * and testing.
193
 */
194
using hb_set_digest_t =
195
  hb_set_digest_combiner_t
196
  <
197
    hb_set_digest_bits_pattern_t<unsigned long, 4>,
198
    hb_set_digest_combiner_t
199
    <
200
      hb_set_digest_bits_pattern_t<unsigned long, 0>,
201
      hb_set_digest_bits_pattern_t<unsigned long, 9>
202
    >
203
  >
204
;
205
206
207
#endif /* HB_SET_DIGEST_HH */