Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / hb-set.cc
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 {
54   hb_set_t *set;
55
56   if (!(set = hb_object_create<hb_set_t> ()))
57     return hb_set_get_empty ();
58
59   return set;
60 }
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 {
74   return const_cast<hb_set_t *> (&Null (hb_set_t));
75 }
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 {
90   return hb_object_reference (set);
91 }
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 {
106   if (!hb_object_destroy (set)) return;
107
108   hb_free (set);
109 }
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 {
132   return hb_object_set_user_data (set, key, data, destroy, replace);
133 }
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 {
151   return hb_object_get_user_data (set, key);
152 }
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 {
168   return !set->in_error ();
169 }
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 {
184   hb_set_t *copy = hb_set_create ();
185   if (unlikely (copy->in_error ()))
186     return hb_set_get_empty ();
187
188   copy->set (*set);
189   return copy;
190 }
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 {
203   /* Immutable-safe. */
204   set->clear ();
205 }
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 {
220   return set->is_empty ();
221 }
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 {
238   return set->has (codepoint);
239 }
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 {
254   /* Immutable-safe. */
255   set->add (codepoint);
256 }
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 {
275   /* Immutable-safe. */
276   set->add_sorted_array (sorted_codepoints,
277                          num_codepoints,
278                          sizeof(hb_codepoint_t));
279 }
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 {
297   /* Immutable-safe. */
298   set->add_range (first, last);
299 }
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 {
314   /* Immutable-safe. */
315   set->del (codepoint);
316 }
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 {
337   /* Immutable-safe. */
338   set->del_range (first, last);
339 }
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 {
357   return set->is_equal (*other);
358 }
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 {
374   return set->hash ();
375 }
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 {
392   return set->is_subset (*larger_set);
393 }
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 {
408   /* Immutable-safe. */
409   set->set (*other);
410 }
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 {
425   /* Immutable-safe. */
426   set->union_ (*other);
427 }
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 {
442   /* Immutable-safe. */
443   set->intersect (*other);
444 }
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 {
459   /* Immutable-safe. */
460   set->subtract (*other);
461 }
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 {
477   /* Immutable-safe. */
478   set->symmetric_difference (*other);
479 }
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 {
492   /* Immutable-safe. */
493   set->invert ();
494 }
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 {
509   return set->is_inverted ();
510 }
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 {
525   return set->get_population ();
526 }
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 {
541   return set->get_min ();
542 }
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 {
557   return set->get_max ();
558 }
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 {
578   return set->next (codepoint);
579 }
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 {
599   return set->previous (codepoint);
600 }
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 {
623   return set->next_range (first, last);
624 }
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 {
647   return set->previous_range (first, last);
648 }
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 {
672   return set->next_many (codepoint, out, size);
673 }