/src/harfbuzz/src/hb-set.cc
Line | Count | Source (jump to first uncovered line) |
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 | | #include "hb-set.hh" |
28 | | |
29 | | |
30 | | /** |
31 | | * SECTION:hb-set |
32 | | * @title: hb-set |
33 | | * @short_description: Objects representing a set of integers |
34 | | * @include: hb.h |
35 | | * |
36 | | * Set objects represent a mathematical set of integer values. They are |
37 | | * used in non-shaping APIs to query certain sets of characters or glyphs, |
38 | | * or other integer values. |
39 | | **/ |
40 | | |
41 | | |
42 | | /** |
43 | | * hb_set_create: |
44 | | * |
45 | | * Creates a new, initially empty set. |
46 | | * |
47 | | * Return value: (transfer full): The new #hb_set_t |
48 | | * |
49 | | * Since: 0.9.2 |
50 | | **/ |
51 | | hb_set_t * |
52 | | hb_set_create () |
53 | 27.7k | { |
54 | 27.7k | hb_set_t *set; |
55 | | |
56 | 27.7k | if (!(set = hb_object_create<hb_set_t> ())) |
57 | 280 | return hb_set_get_empty (); |
58 | | |
59 | 27.5k | return set; |
60 | 27.7k | } |
61 | | |
62 | | /** |
63 | | * hb_set_get_empty: |
64 | | * |
65 | | * Fetches the singleton empty #hb_set_t. |
66 | | * |
67 | | * Return value: (transfer full): The empty #hb_set_t |
68 | | * |
69 | | * Since: 0.9.2 |
70 | | **/ |
71 | | hb_set_t * |
72 | | hb_set_get_empty () |
73 | 280 | { |
74 | 280 | return const_cast<hb_set_t *> (&Null (hb_set_t)); |
75 | 280 | } |
76 | | |
77 | | /** |
78 | | * hb_set_reference: (skip) |
79 | | * @set: A set |
80 | | * |
81 | | * Increases the reference count on a set. |
82 | | * |
83 | | * Return value: (transfer full): The set |
84 | | * |
85 | | * Since: 0.9.2 |
86 | | **/ |
87 | | hb_set_t * |
88 | | hb_set_reference (hb_set_t *set) |
89 | 0 | { |
90 | 0 | return hb_object_reference (set); |
91 | 0 | } |
92 | | |
93 | | /** |
94 | | * hb_set_destroy: (skip) |
95 | | * @set: A set |
96 | | * |
97 | | * Decreases the reference count on a set. When |
98 | | * the reference count reaches zero, the set is |
99 | | * destroyed, freeing all memory. |
100 | | * |
101 | | * Since: 0.9.2 |
102 | | **/ |
103 | | void |
104 | | hb_set_destroy (hb_set_t *set) |
105 | 27.7k | { |
106 | 27.7k | if (!hb_object_destroy (set)) return; |
107 | | |
108 | 27.5k | hb_free (set); |
109 | 27.5k | } |
110 | | |
111 | | /** |
112 | | * hb_set_set_user_data: (skip) |
113 | | * @set: A set |
114 | | * @key: The user-data key to set |
115 | | * @data: A pointer to the user data to set |
116 | | * @destroy: (nullable): A callback to call when @data is not needed anymore |
117 | | * @replace: Whether to replace an existing data with the same key |
118 | | * |
119 | | * Attaches a user-data key/data pair to the specified set. |
120 | | * |
121 | | * Return value: `true` if success, `false` otherwise |
122 | | * |
123 | | * Since: 0.9.2 |
124 | | **/ |
125 | | hb_bool_t |
126 | | hb_set_set_user_data (hb_set_t *set, |
127 | | hb_user_data_key_t *key, |
128 | | void * data, |
129 | | hb_destroy_func_t destroy, |
130 | | hb_bool_t replace) |
131 | 0 | { |
132 | 0 | return hb_object_set_user_data (set, key, data, destroy, replace); |
133 | 0 | } |
134 | | |
135 | | /** |
136 | | * hb_set_get_user_data: (skip) |
137 | | * @set: A set |
138 | | * @key: The user-data key to query |
139 | | * |
140 | | * Fetches the user data associated with the specified key, |
141 | | * attached to the specified set. |
142 | | * |
143 | | * Return value: (transfer none): A pointer to the user data |
144 | | * |
145 | | * Since: 0.9.2 |
146 | | **/ |
147 | | void * |
148 | | hb_set_get_user_data (const hb_set_t *set, |
149 | | hb_user_data_key_t *key) |
150 | 0 | { |
151 | 0 | return hb_object_get_user_data (set, key); |
152 | 0 | } |
153 | | |
154 | | |
155 | | /** |
156 | | * hb_set_allocation_successful: |
157 | | * @set: A set |
158 | | * |
159 | | * Tests whether memory allocation for a set was successful. |
160 | | * |
161 | | * Return value: `true` if allocation succeeded, `false` otherwise |
162 | | * |
163 | | * Since: 0.9.2 |
164 | | **/ |
165 | | hb_bool_t |
166 | | hb_set_allocation_successful (const hb_set_t *set) |
167 | 0 | { |
168 | 0 | return !set->in_error (); |
169 | 0 | } |
170 | | |
171 | | /** |
172 | | * hb_set_copy: |
173 | | * @set: A set |
174 | | * |
175 | | * Allocate a copy of @set. |
176 | | * |
177 | | * Return value: (transfer full): Newly-allocated set. |
178 | | * |
179 | | * Since: 2.8.2 |
180 | | **/ |
181 | | hb_set_t * |
182 | | hb_set_copy (const hb_set_t *set) |
183 | 0 | { |
184 | 0 | hb_set_t *copy = hb_set_create (); |
185 | 0 | if (unlikely (copy->in_error ())) |
186 | 0 | return hb_set_get_empty (); |
187 | | |
188 | 0 | copy->set (*set); |
189 | 0 | return copy; |
190 | 0 | } |
191 | | |
192 | | /** |
193 | | * hb_set_clear: |
194 | | * @set: A set |
195 | | * |
196 | | * Clears out the contents of a set. |
197 | | * |
198 | | * Since: 0.9.2 |
199 | | **/ |
200 | | void |
201 | | hb_set_clear (hb_set_t *set) |
202 | 0 | { |
203 | | /* Immutable-safe. */ |
204 | 0 | set->clear (); |
205 | 0 | } |
206 | | |
207 | | /** |
208 | | * hb_set_is_empty: |
209 | | * @set: a set. |
210 | | * |
211 | | * Tests whether a set is empty (contains no elements). |
212 | | * |
213 | | * Return value: `true` if @set is empty |
214 | | * |
215 | | * Since: 0.9.7 |
216 | | **/ |
217 | | hb_bool_t |
218 | | hb_set_is_empty (const hb_set_t *set) |
219 | 0 | { |
220 | 0 | return set->is_empty (); |
221 | 0 | } |
222 | | |
223 | | /** |
224 | | * hb_set_has: |
225 | | * @set: A set |
226 | | * @codepoint: The element to query |
227 | | * |
228 | | * Tests whether @codepoint belongs to @set. |
229 | | * |
230 | | * Return value: `true` if @codepoint is in @set, `false` otherwise |
231 | | * |
232 | | * Since: 0.9.2 |
233 | | **/ |
234 | | hb_bool_t |
235 | | hb_set_has (const hb_set_t *set, |
236 | | hb_codepoint_t codepoint) |
237 | 0 | { |
238 | 0 | return set->has (codepoint); |
239 | 0 | } |
240 | | |
241 | | /** |
242 | | * hb_set_add: |
243 | | * @set: A set |
244 | | * @codepoint: The element to add to @set |
245 | | * |
246 | | * Adds @codepoint to @set. |
247 | | * |
248 | | * Since: 0.9.2 |
249 | | **/ |
250 | | void |
251 | | hb_set_add (hb_set_t *set, |
252 | | hb_codepoint_t codepoint) |
253 | 0 | { |
254 | | /* Immutable-safe. */ |
255 | 0 | set->add (codepoint); |
256 | 0 | } |
257 | | |
258 | | /** |
259 | | * hb_set_add_sorted_array: |
260 | | * @set: A set |
261 | | * @sorted_codepoints: (array length=num_codepoints): Array of codepoints to add |
262 | | * @num_codepoints: Length of @sorted_codepoints |
263 | | * |
264 | | * Adds @num_codepoints codepoints to a set at once. |
265 | | * The codepoints array must be in increasing order, |
266 | | * with size at least @num_codepoints. |
267 | | * |
268 | | * Since: 4.1.0 |
269 | | */ |
270 | | HB_EXTERN void |
271 | | hb_set_add_sorted_array (hb_set_t *set, |
272 | | const hb_codepoint_t *sorted_codepoints, |
273 | | unsigned int num_codepoints) |
274 | 0 | { |
275 | | /* Immutable-safe. */ |
276 | 0 | set->add_sorted_array (sorted_codepoints, |
277 | 0 | num_codepoints, |
278 | 0 | sizeof(hb_codepoint_t)); |
279 | 0 | } |
280 | | |
281 | | /** |
282 | | * hb_set_add_range: |
283 | | * @set: A set |
284 | | * @first: The first element to add to @set |
285 | | * @last: The final element to add to @set |
286 | | * |
287 | | * Adds all of the elements from @first to @last |
288 | | * (inclusive) to @set. |
289 | | * |
290 | | * Since: 0.9.7 |
291 | | **/ |
292 | | void |
293 | | hb_set_add_range (hb_set_t *set, |
294 | | hb_codepoint_t first, |
295 | | hb_codepoint_t last) |
296 | 0 | { |
297 | | /* Immutable-safe. */ |
298 | 0 | set->add_range (first, last); |
299 | 0 | } |
300 | | |
301 | | /** |
302 | | * hb_set_del: |
303 | | * @set: A set |
304 | | * @codepoint: Removes @codepoint from @set |
305 | | * |
306 | | * Removes @codepoint from @set. |
307 | | * |
308 | | * Since: 0.9.2 |
309 | | **/ |
310 | | void |
311 | | hb_set_del (hb_set_t *set, |
312 | | hb_codepoint_t codepoint) |
313 | 0 | { |
314 | | /* Immutable-safe. */ |
315 | 0 | set->del (codepoint); |
316 | 0 | } |
317 | | |
318 | | /** |
319 | | * hb_set_del_range: |
320 | | * @set: A set |
321 | | * @first: The first element to remove from @set |
322 | | * @last: The final element to remove from @set |
323 | | * |
324 | | * Removes all of the elements from @first to @last |
325 | | * (inclusive) from @set. |
326 | | * |
327 | | * If @last is #HB_SET_VALUE_INVALID, then all values |
328 | | * greater than or equal to @first are removed. |
329 | | * |
330 | | * Since: 0.9.7 |
331 | | **/ |
332 | | void |
333 | | hb_set_del_range (hb_set_t *set, |
334 | | hb_codepoint_t first, |
335 | | hb_codepoint_t last) |
336 | 0 | { |
337 | | /* Immutable-safe. */ |
338 | 0 | set->del_range (first, last); |
339 | 0 | } |
340 | | |
341 | | /** |
342 | | * hb_set_is_equal: |
343 | | * @set: A set |
344 | | * @other: Another set |
345 | | * |
346 | | * Tests whether @set and @other are equal (contain the same |
347 | | * elements). |
348 | | * |
349 | | * Return value: `true` if the two sets are equal, `false` otherwise. |
350 | | * |
351 | | * Since: 0.9.7 |
352 | | **/ |
353 | | hb_bool_t |
354 | | hb_set_is_equal (const hb_set_t *set, |
355 | | const hb_set_t *other) |
356 | 0 | { |
357 | 0 | return set->is_equal (*other); |
358 | 0 | } |
359 | | |
360 | | /** |
361 | | * hb_set_hash: |
362 | | * @set: A set |
363 | | * |
364 | | * Creates a hash representing @set. |
365 | | * |
366 | | * Return value: |
367 | | * A hash of @set. |
368 | | * |
369 | | * Since: 4.4.0 |
370 | | **/ |
371 | | HB_EXTERN unsigned int |
372 | | hb_set_hash (const hb_set_t *set) |
373 | 0 | { |
374 | 0 | return set->hash (); |
375 | 0 | } |
376 | | |
377 | | /** |
378 | | * hb_set_is_subset: |
379 | | * @set: A set |
380 | | * @larger_set: Another set |
381 | | * |
382 | | * Tests whether @set is a subset of @larger_set. |
383 | | * |
384 | | * Return value: `true` if the @set is a subset of (or equal to) @larger_set, `false` otherwise. |
385 | | * |
386 | | * Since: 1.8.1 |
387 | | **/ |
388 | | hb_bool_t |
389 | | hb_set_is_subset (const hb_set_t *set, |
390 | | const hb_set_t *larger_set) |
391 | 0 | { |
392 | 0 | return set->is_subset (*larger_set); |
393 | 0 | } |
394 | | |
395 | | /** |
396 | | * hb_set_set: |
397 | | * @set: A set |
398 | | * @other: Another set |
399 | | * |
400 | | * Makes the contents of @set equal to the contents of @other. |
401 | | * |
402 | | * Since: 0.9.2 |
403 | | **/ |
404 | | void |
405 | | hb_set_set (hb_set_t *set, |
406 | | const hb_set_t *other) |
407 | 0 | { |
408 | | /* Immutable-safe. */ |
409 | 0 | set->set (*other); |
410 | 0 | } |
411 | | |
412 | | /** |
413 | | * hb_set_union: |
414 | | * @set: A set |
415 | | * @other: Another set |
416 | | * |
417 | | * Makes @set the union of @set and @other. |
418 | | * |
419 | | * Since: 0.9.2 |
420 | | **/ |
421 | | void |
422 | | hb_set_union (hb_set_t *set, |
423 | | const hb_set_t *other) |
424 | 0 | { |
425 | | /* Immutable-safe. */ |
426 | 0 | set->union_ (*other); |
427 | 0 | } |
428 | | |
429 | | /** |
430 | | * hb_set_intersect: |
431 | | * @set: A set |
432 | | * @other: Another set |
433 | | * |
434 | | * Makes @set the intersection of @set and @other. |
435 | | * |
436 | | * Since: 0.9.2 |
437 | | **/ |
438 | | void |
439 | | hb_set_intersect (hb_set_t *set, |
440 | | const hb_set_t *other) |
441 | 0 | { |
442 | | /* Immutable-safe. */ |
443 | 0 | set->intersect (*other); |
444 | 0 | } |
445 | | |
446 | | /** |
447 | | * hb_set_subtract: |
448 | | * @set: A set |
449 | | * @other: Another set |
450 | | * |
451 | | * Subtracts the contents of @other from @set. |
452 | | * |
453 | | * Since: 0.9.2 |
454 | | **/ |
455 | | void |
456 | | hb_set_subtract (hb_set_t *set, |
457 | | const hb_set_t *other) |
458 | 0 | { |
459 | | /* Immutable-safe. */ |
460 | 0 | set->subtract (*other); |
461 | 0 | } |
462 | | |
463 | | /** |
464 | | * hb_set_symmetric_difference: |
465 | | * @set: A set |
466 | | * @other: Another set |
467 | | * |
468 | | * Makes @set the symmetric difference of @set |
469 | | * and @other. |
470 | | * |
471 | | * Since: 0.9.2 |
472 | | **/ |
473 | | void |
474 | | hb_set_symmetric_difference (hb_set_t *set, |
475 | | const hb_set_t *other) |
476 | 0 | { |
477 | | /* Immutable-safe. */ |
478 | 0 | set->symmetric_difference (*other); |
479 | 0 | } |
480 | | |
481 | | /** |
482 | | * hb_set_invert: |
483 | | * @set: A set |
484 | | * |
485 | | * Inverts the contents of @set. |
486 | | * |
487 | | * Since: 3.0.0 |
488 | | **/ |
489 | | void |
490 | | hb_set_invert (hb_set_t *set) |
491 | 0 | { |
492 | | /* Immutable-safe. */ |
493 | 0 | set->invert (); |
494 | 0 | } |
495 | | |
496 | | /** |
497 | | * hb_set_is_inverted: |
498 | | * @set: A set |
499 | | * |
500 | | * Returns whether the set is inverted. |
501 | | * |
502 | | * Return value: `true` if the set is inverted, `false` otherwise |
503 | | * |
504 | | * Since: 7.0.0 |
505 | | **/ |
506 | | hb_bool_t |
507 | | hb_set_is_inverted (const hb_set_t *set) |
508 | 0 | { |
509 | 0 | return set->is_inverted (); |
510 | 0 | } |
511 | | |
512 | | /** |
513 | | * hb_set_get_population: |
514 | | * @set: A set |
515 | | * |
516 | | * Returns the number of elements in the set. |
517 | | * |
518 | | * Return value: The population of @set |
519 | | * |
520 | | * Since: 0.9.7 |
521 | | **/ |
522 | | unsigned int |
523 | | hb_set_get_population (const hb_set_t *set) |
524 | 0 | { |
525 | 0 | return set->get_population (); |
526 | 0 | } |
527 | | |
528 | | /** |
529 | | * hb_set_get_min: |
530 | | * @set: A set |
531 | | * |
532 | | * Finds the smallest element in the set. |
533 | | * |
534 | | * Return value: minimum of @set, or #HB_SET_VALUE_INVALID if @set is empty. |
535 | | * |
536 | | * Since: 0.9.7 |
537 | | **/ |
538 | | hb_codepoint_t |
539 | | hb_set_get_min (const hb_set_t *set) |
540 | 0 | { |
541 | 0 | return set->get_min (); |
542 | 0 | } |
543 | | |
544 | | /** |
545 | | * hb_set_get_max: |
546 | | * @set: A set |
547 | | * |
548 | | * Finds the largest element in the set. |
549 | | * |
550 | | * Return value: maximum of @set, or #HB_SET_VALUE_INVALID if @set is empty. |
551 | | * |
552 | | * Since: 0.9.7 |
553 | | **/ |
554 | | hb_codepoint_t |
555 | | hb_set_get_max (const hb_set_t *set) |
556 | 0 | { |
557 | 0 | return set->get_max (); |
558 | 0 | } |
559 | | |
560 | | /** |
561 | | * hb_set_next: |
562 | | * @set: A set |
563 | | * @codepoint: (inout): Input = Code point to query |
564 | | * Output = Code point retrieved |
565 | | * |
566 | | * Fetches the next element in @set that is greater than current value of @codepoint. |
567 | | * |
568 | | * Set @codepoint to #HB_SET_VALUE_INVALID to get started. |
569 | | * |
570 | | * Return value: `true` if there was a next value, `false` otherwise |
571 | | * |
572 | | * Since: 0.9.2 |
573 | | **/ |
574 | | hb_bool_t |
575 | | hb_set_next (const hb_set_t *set, |
576 | | hb_codepoint_t *codepoint) |
577 | 0 | { |
578 | 0 | return set->next (codepoint); |
579 | 0 | } |
580 | | |
581 | | /** |
582 | | * hb_set_previous: |
583 | | * @set: A set |
584 | | * @codepoint: (inout): Input = Code point to query |
585 | | * Output = Code point retrieved |
586 | | * |
587 | | * Fetches the previous element in @set that is lower than current value of @codepoint. |
588 | | * |
589 | | * Set @codepoint to #HB_SET_VALUE_INVALID to get started. |
590 | | * |
591 | | * Return value: `true` if there was a previous value, `false` otherwise |
592 | | * |
593 | | * Since: 1.8.0 |
594 | | **/ |
595 | | hb_bool_t |
596 | | hb_set_previous (const hb_set_t *set, |
597 | | hb_codepoint_t *codepoint) |
598 | 0 | { |
599 | 0 | return set->previous (codepoint); |
600 | 0 | } |
601 | | |
602 | | /** |
603 | | * hb_set_next_range: |
604 | | * @set: A set |
605 | | * @first: (out): The first code point in the range |
606 | | * @last: (inout): Input = The current last code point in the range |
607 | | * Output = The last code point in the range |
608 | | * |
609 | | * Fetches the next consecutive range of elements in @set that |
610 | | * are greater than current value of @last. |
611 | | * |
612 | | * Set @last to #HB_SET_VALUE_INVALID to get started. |
613 | | * |
614 | | * Return value: `true` if there was a next range, `false` otherwise |
615 | | * |
616 | | * Since: 0.9.7 |
617 | | **/ |
618 | | hb_bool_t |
619 | | hb_set_next_range (const hb_set_t *set, |
620 | | hb_codepoint_t *first, |
621 | | hb_codepoint_t *last) |
622 | 0 | { |
623 | 0 | return set->next_range (first, last); |
624 | 0 | } |
625 | | |
626 | | /** |
627 | | * hb_set_previous_range: |
628 | | * @set: A set |
629 | | * @first: (inout): Input = The current first code point in the range |
630 | | * Output = The first code point in the range |
631 | | * @last: (out): The last code point in the range |
632 | | * |
633 | | * Fetches the previous consecutive range of elements in @set that |
634 | | * are greater than current value of @last. |
635 | | * |
636 | | * Set @first to #HB_SET_VALUE_INVALID to get started. |
637 | | * |
638 | | * Return value: `true` if there was a previous range, `false` otherwise |
639 | | * |
640 | | * Since: 1.8.0 |
641 | | **/ |
642 | | hb_bool_t |
643 | | hb_set_previous_range (const hb_set_t *set, |
644 | | hb_codepoint_t *first, |
645 | | hb_codepoint_t *last) |
646 | 0 | { |
647 | 0 | return set->previous_range (first, last); |
648 | 0 | } |
649 | | |
650 | | /** |
651 | | * hb_set_next_many: |
652 | | * @set: A set |
653 | | * @codepoint: Outputting codepoints starting after this one. |
654 | | * Use #HB_SET_VALUE_INVALID to get started. |
655 | | * @out: (array length=size): An array of codepoints to write to. |
656 | | * @size: The maximum number of codepoints to write out. |
657 | | * |
658 | | * Finds the next element in @set that is greater than @codepoint. Writes out |
659 | | * codepoints to @out, until either the set runs out of elements, or @size |
660 | | * codepoints are written, whichever comes first. |
661 | | * |
662 | | * Return value: the number of values written. |
663 | | * |
664 | | * Since: 4.2.0 |
665 | | **/ |
666 | | unsigned int |
667 | | hb_set_next_many (const hb_set_t *set, |
668 | | hb_codepoint_t codepoint, |
669 | | hb_codepoint_t *out, |
670 | | unsigned int size) |
671 | 0 | { |
672 | 0 | return set->next_many (codepoint, out, size); |
673 | 0 | } |