Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / test-map.cc
1 /*
2  * Copyright © 2021  Behdad Esfahbod
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
25 #include "hb.hh"
26 #include "hb-map.hh"
27 #include "hb-set.hh"
28 #include <string>
29
30 int
31 main (int argc, char **argv)
32 {
33
34   /* Test copy constructor. */
35   {
36     hb_map_t v1;
37     v1.set (1, 2);
38     hb_map_t v2 {v1};
39     assert (v1.get_population () == 1);
40     assert (v2.get_population () == 1);
41     assert (v1[1] == 2);
42     assert (v2[1] == 2);
43   }
44
45   /* Test copy assignment. */
46   {
47     hb_map_t v1;
48     v1.set (1, 2);
49     hb_map_t v2 = v1;
50     assert (v1.get_population () == 1);
51     assert (v2.get_population () == 1);
52     assert (v1[1] == 2);
53     assert (v2[1] == 2);
54   }
55
56   /* Test move constructor. */
57   {
58     hb_map_t s {};
59     s.set (1, 2);
60     hb_map_t v (std::move (s));
61     assert (s.get_population () == 0);
62     assert (v.get_population () == 1);
63   }
64
65   /* Test move assignment. */
66   {
67     hb_map_t s {};
68     s.set (1, 2);
69     hb_map_t v;
70     v = std::move (s);
71     assert (s.get_population () == 0);
72     assert (v.get_population () == 1);
73   }
74
75   /* Test initializing from iterable. */
76   {
77     hb_map_t s;
78
79     s.set (1, 2);
80     s.set (3, 4);
81
82     hb_vector_t<hb_codepoint_pair_t> v (s);
83     hb_map_t v0 (v);
84     hb_map_t v1 (s);
85     hb_map_t v2 (std::move (s));
86
87     assert (s.get_population () == 0);
88     assert (v0.get_population () == 2);
89     assert (v1.get_population () == 2);
90     assert (v2.get_population () == 2);
91   }
92
93   /* Test call fini() twice. */
94   {
95     hb_map_t s;
96     for (int i = 0; i < 16; i++)
97       s.set(i, i+1);
98     s.fini();
99   }
100
101   /* Test initializing from iterator. */
102   {
103     hb_map_t s;
104
105     s.set (1, 2);
106     s.set (3, 4);
107
108     hb_map_t v (hb_iter (s));
109
110     assert (v.get_population () == 2);
111   }
112
113   /* Test initializing from initializer list and swapping. */
114   {
115     using pair_t = hb_codepoint_pair_t;
116     hb_map_t v1 {pair_t{1,2}, pair_t{4,5}};
117     hb_map_t v2 {pair_t{3,4}};
118     hb_swap (v1, v2);
119     assert (v1.get_population () == 1);
120     assert (v2.get_population () == 2);
121   }
122
123   /* Test class key / value types. */
124   {
125     hb_hashmap_t<hb_bytes_t, int> m1;
126     hb_hashmap_t<int, hb_bytes_t> m2;
127     hb_hashmap_t<hb_bytes_t, hb_bytes_t> m3;
128     assert (m1.get_population () == 0);
129     assert (m2.get_population () == 0);
130     assert (m3.get_population () == 0);
131   }
132
133   {
134     hb_hashmap_t<int, int> m0;
135     hb_hashmap_t<std::string, int> m1;
136     hb_hashmap_t<int, std::string> m2;
137     hb_hashmap_t<std::string, std::string> m3;
138
139     std::string s;
140     for (unsigned i = 1; i < 1000; i++)
141     {
142       s += "x";
143       m0.set (i, i);
144       m1.set (s, i);
145       m2.set (i, s);
146       m3.set (s, s);
147     }
148   }
149
150   /* Test hashing maps. */
151   {
152     using pair = hb_codepoint_pair_t;
153
154     hb_hashmap_t<hb_map_t, hb_map_t> m1;
155
156     m1.set (hb_map_t (), hb_map_t {});
157     m1.set (hb_map_t (), hb_map_t {pair (1u, 2u)});
158     m1.set (hb_map_t {pair (1u, 2u)}, hb_map_t {pair (2u, 3u)});
159
160     assert (m1.get (hb_map_t ()) == hb_map_t {pair (1u, 2u)});
161     assert (m1.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)});
162   }
163
164   /* Test hashing sets. */
165   {
166     hb_hashmap_t<hb_set_t, hb_set_t> m1;
167
168     m1.set (hb_set_t (), hb_set_t ());
169     m1.set (hb_set_t (), hb_set_t {1});
170     m1.set (hb_set_t {1, 1000}, hb_set_t {2});
171
172     assert (m1.get (hb_set_t ()) == hb_set_t {1});
173     assert (m1.get (hb_set_t {1000, 1}) == hb_set_t {2});
174   }
175
176   /* Test hashing vectors. */
177   {
178     using vector_t = hb_vector_t<unsigned>;
179
180     hb_hashmap_t<vector_t, vector_t> m1;
181
182     m1.set (vector_t (), vector_t {1});
183     m1.set (vector_t {1}, vector_t {2});
184
185     m1 << hb_pair_t<vector_t, vector_t> {vector_t {2}, vector_t ()};
186
187     assert (m1.get (vector_t ()) == vector_t {1});
188     assert (m1.get (vector_t {1}) == vector_t {2});
189   }
190
191   /* Test moving values */
192   {
193     using vector_t = hb_vector_t<unsigned>;
194
195     hb_hashmap_t<vector_t, vector_t> m1;
196     vector_t v {3};
197     assert (v.length == 1);
198     m1 << hb_pair_t<vector_t, vector_t> {vector_t {3}, v};
199     assert (v.length == 1);
200     m1 << hb_pair_t<vector_t, vector_t&&> {vector_t {4}, std::move (v)};
201     assert (v.length == 0);
202     m1 << hb_pair_t<vector_t&&, vector_t> {vector_t {4}, vector_t {5}};
203     m1 << hb_pair_t<vector_t&&, vector_t&&> {vector_t {4}, vector_t {5}};
204
205     hb_hashmap_t<vector_t, vector_t> m2;
206     vector_t v2 {3};
207     m2.set (vector_t {4}, v2);
208     assert (v2.length == 1);
209     m2.set (vector_t {5}, std::move (v2));
210     assert (v2.length == 0);
211   }
212
213   /* Test hb::shared_ptr. */
214   {
215     hb_hashmap_t<hb::shared_ptr<hb_set_t>, hb::shared_ptr<hb_set_t>> m;
216
217     m.set (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()),
218            hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
219     m.get (hb::shared_ptr<hb_set_t> (hb_set_get_empty ()));
220     m.iter ();
221     m.keys ();
222     m.values ();
223     m.iter_ref ();
224     m.keys_ref ();
225     m.values_ref ();
226   }
227   /* Test hb::unique_ptr. */
228   {
229     hb_hashmap_t<hb::unique_ptr<hb_set_t>, hb::unique_ptr<hb_set_t>> m;
230
231     m.set (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()),
232            hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
233     m.get (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()));
234     hb::unique_ptr<hb_set_t> *v;
235     m.has (hb::unique_ptr<hb_set_t> (hb_set_get_empty ()), &v);
236     m.iter_ref ();
237     m.keys_ref ();
238     m.values_ref ();
239   }
240   /* Test hashmap with complex shared_ptrs as keys. */
241   {
242     hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> m;
243
244     hb_map_t *m1 = hb_map_create ();
245     hb_map_t *m2 = hb_map_create ();
246     m1->set (1,3);
247     m2->set (1,3);
248
249     hb::shared_ptr<hb_map_t> p1 {m1};
250     hb::shared_ptr<hb_map_t> p2 {m2};
251     m.set (p1,1);
252
253     assert (m.has (p2));
254
255     m1->set (2,4);
256     assert (!m.has (p2));
257   }
258   /* Test value type with hb_bytes_t. */
259   {
260     hb_hashmap_t<int, hb_bytes_t> m;
261     char c_str[] = "Test";
262     hb_bytes_t bytes (c_str);
263
264     m.set (1, bytes);
265     assert (m.has (1));
266     assert (m.get (1) == hb_bytes_t {"Test"});
267   }
268   /* Test operators. */
269   {
270     hb_map_t m1, m2, m3;
271     m1.set (1, 2);
272     m1.set (2, 4);
273     m2.set (1, 2);
274     m2.set (2, 4);
275     m3.set (1, 3);
276     m3.set (3, 5);
277
278     assert (m1 == m2);
279     assert (m1 != m3);
280     assert (!(m2 == m3));
281
282     m2 = m3;
283     assert (m2.has (1));
284     assert (!m2.has (2));
285     assert (m2.has (3));
286
287     assert (m3.has (3));
288   }
289   /* Test reset. */
290   {
291     hb_hashmap_t<int, hb_set_t> m;
292     m.set (1, hb_set_t {1, 2, 3});
293     m.reset ();
294   }
295   /* Test iteration. */
296   {
297     hb_map_t m;
298     m.set (1, 1);
299     m.set (4, 3);
300     m.set (5, 5);
301     m.set (2, 1);
302     m.set (3, 2);
303     m.set (6, 8);
304
305     hb_codepoint_t k;
306     hb_codepoint_t v;
307     unsigned pop = 0;
308     for (signed i = -1;
309          m.next (&i, &k, &v);)
310     {
311       pop++;
312            if (k == 1) assert (v == 1);
313       else if (k == 2) assert (v == 1);
314       else if (k == 3) assert (v == 2);
315       else if (k == 4) assert (v == 3);
316       else if (k == 5) assert (v == 5);
317       else if (k == 6) assert (v == 8);
318       else assert (false);
319     }
320     assert (pop == m.get_population ());
321   }
322   /* Test update */
323   {
324     hb_map_t m1, m2;
325     m1.set (1, 2);
326     m1.set (2, 4);
327     m2.set (1, 3);
328
329     m1.update (m2);
330     assert (m1.get_population () == 2);
331     assert (m1[1] == 3);
332     assert (m1[2] == 4);
333   }
334   /* Test keys / values */
335   {
336     hb_map_t m;
337     m.set (1, 1);
338     m.set (4, 3);
339     m.set (5, 5);
340     m.set (2, 1);
341     m.set (3, 2);
342     m.set (6, 8);
343
344     hb_set_t keys;
345     hb_set_t values;
346
347     hb_copy (m.keys (), keys);
348     hb_copy (m.values (), values);
349
350     assert (keys.is_equal (hb_set_t ({1, 2, 3, 4, 5, 6})));
351     assert (values.is_equal (hb_set_t ({1, 1, 2, 3, 5, 8})));
352
353     assert (keys.is_equal (hb_set_t (m.keys ())));
354     assert (values.is_equal (hb_set_t (m.values ())));
355   }
356
357   return 0;
358 }