Coverage Report

Created: 2024-04-26 11:06

/src/harfbuzz/src/hb-bimap.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2019 Adobe 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
 * Adobe Author(s): Michiharu Ariza
25
 */
26
27
#ifndef HB_BIMAP_HH
28
#define HB_BIMAP_HH
29
30
#include "hb.hh"
31
#include "hb-map.hh"
32
33
/* Bi-directional map */
34
struct hb_bimap_t
35
{
36
  void reset ()
37
0
  {
38
0
    forw_map.reset ();
39
0
    back_map.reset ();
40
0
  }
41
42
  void resize (unsigned pop)
43
0
  {
44
0
    forw_map.resize (pop);
45
0
    back_map.resize (pop);
46
0
  }
47
48
0
  bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
49
50
  void set (hb_codepoint_t lhs, hb_codepoint_t rhs)
51
0
  {
52
0
    if (in_error ()) return;
53
0
    if (unlikely (lhs == HB_MAP_VALUE_INVALID)) return;
54
0
    if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; }
55
0
56
0
    forw_map.set (lhs, rhs);
57
0
    if (unlikely (in_error ())) return;
58
0
59
0
    back_map.set (rhs, lhs);
60
0
    if (unlikely (in_error ())) forw_map.del (lhs);
61
0
  }
62
63
0
  hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
64
0
  hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
65
66
0
  hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
67
0
  bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); }
68
69
70
  void del (hb_codepoint_t lhs)
71
0
  {
72
0
    back_map.del (get (lhs));
73
0
    forw_map.del (lhs);
74
0
  }
75
76
  void clear ()
77
0
  {
78
0
    forw_map.clear ();
79
0
    back_map.clear ();
80
0
  }
81
82
0
  bool is_empty () const { return forw_map.is_empty (); }
83
84
0
  unsigned int get_population () const { return forw_map.get_population (); }
85
86
  protected:
87
  hb_map_t  forw_map;
88
  hb_map_t  back_map;
89
};
90
91
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
92
struct hb_inc_bimap_t : hb_bimap_t
93
{
94
  /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
95
   * Return the rhs value as the result.
96
   */
97
  hb_codepoint_t add (hb_codepoint_t lhs)
98
0
  {
99
0
    hb_codepoint_t  rhs = forw_map[lhs];
100
0
    if (rhs == HB_MAP_VALUE_INVALID)
101
0
    {
102
0
      rhs = next_value++;
103
0
      set (lhs, rhs);
104
0
    }
105
0
    return rhs;
106
0
  }
107
108
  hb_codepoint_t skip ()
109
0
  { return next_value++; }
110
111
  hb_codepoint_t get_next_value () const
112
0
  { return next_value; }
113
114
  void add_set (const hb_set_t *set)
115
0
  {
116
0
    hb_codepoint_t i = HB_SET_VALUE_INVALID;
117
0
    while (hb_set_next (set, &i)) add (i);
118
0
  }
119
120
  /* Create an identity map. */
121
  bool identity (unsigned int size)
122
0
  {
123
0
    clear ();
124
0
    for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
125
0
    return !in_error ();
126
0
  }
127
128
  protected:
129
  static int cmp_id (const void* a, const void* b)
130
0
  { return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
131
132
  public:
133
  /* Optional: after finished adding all mappings in a random order,
134
   * reassign rhs to lhs so that they are in the same order. */
135
  void sort ()
136
0
  {
137
0
    hb_codepoint_t  count = get_population ();
138
0
    hb_vector_t <hb_codepoint_t> work;
139
0
    work.resize (count);
140
0
141
0
    for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
142
0
      work[rhs] = back_map[rhs];
143
0
144
0
    work.qsort (cmp_id);
145
0
146
0
    clear ();
147
0
    for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
148
0
      set (work[rhs], rhs);
149
0
  }
150
151
  protected:
152
  unsigned int next_value = 0;
153
};
154
155
#endif /* HB_BIMAP_HH */