Coverage Report

Created: 2023-06-07 06:14

/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
87
  protected:
88
  hb_map_t  forw_map;
89
  hb_map_t  back_map;
90
91
  public:
92
  auto keys () const HB_AUTO_RETURN (+ forw_map.keys())
93
  auto values () const HB_AUTO_RETURN (+ forw_map.values())
94
  auto iter () const HB_AUTO_RETURN (+ forw_map.iter())
95
};
96
97
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
98
struct hb_inc_bimap_t : hb_bimap_t
99
{
100
  /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
101
   * Return the rhs value as the result.
102
   */
103
  hb_codepoint_t add (hb_codepoint_t lhs)
104
0
  {
105
0
    hb_codepoint_t  rhs = forw_map[lhs];
106
0
    if (rhs == HB_MAP_VALUE_INVALID)
107
0
    {
108
0
      rhs = next_value++;
109
0
      set (lhs, rhs);
110
0
    }
111
0
    return rhs;
112
0
  }
113
114
  hb_codepoint_t skip ()
115
0
  { return next_value++; }
116
117
  hb_codepoint_t skip (unsigned count)
118
0
  { return next_value += count; }
119
120
  hb_codepoint_t get_next_value () const
121
0
  { return next_value; }
122
123
  void add_set (const hb_set_t *set)
124
0
  {
125
0
    hb_codepoint_t i = HB_SET_VALUE_INVALID;
126
0
    while (hb_set_next (set, &i)) add (i);
127
0
  }
128
129
  /* Create an identity map. */
130
  bool identity (unsigned int size)
131
0
  {
132
0
    clear ();
133
0
    for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
134
0
    return !in_error ();
135
0
  }
136
137
  protected:
138
  static int cmp_id (const void* a, const void* b)
139
0
  { return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
140
141
  public:
142
  /* Optional: after finished adding all mappings in a random order,
143
   * reassign rhs to lhs so that they are in the same order. */
144
  void sort ()
145
0
  {
146
0
    hb_codepoint_t  count = get_population ();
147
0
    hb_vector_t <hb_codepoint_t> work;
148
0
    work.resize (count);
149
0
150
0
    for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
151
0
      work[rhs] = back_map[rhs];
152
0
153
0
    work.qsort (cmp_id);
154
0
155
0
    clear ();
156
0
    for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
157
0
      set (work[rhs], rhs);
158
0
  }
159
160
  protected:
161
  unsigned int next_value = 0;
162
};
163
164
#endif /* HB_BIMAP_HH */