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: (Xconstructor)
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 *
hb_set_create()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 set->init_shallow ();
60
61 return set;
62 }
63
64 /**
65 * hb_set_get_empty:
66 *
67 * Fetches the singleton empty #hb_set_t.
68 *
69 * Return value: (transfer full): The empty #hb_set_t
70 *
71 * Since: 0.9.2
72 **/
73 hb_set_t *
hb_set_get_empty()74 hb_set_get_empty ()
75 {
76 return const_cast<hb_set_t *> (&Null (hb_set_t));
77 }
78
79 /**
80 * hb_set_reference: (skip)
81 * @set: A set
82 *
83 * Increases the reference count on a set.
84 *
85 * Return value: (transfer full): The set
86 *
87 * Since: 0.9.2
88 **/
89 hb_set_t *
hb_set_reference(hb_set_t * set)90 hb_set_reference (hb_set_t *set)
91 {
92 return hb_object_reference (set);
93 }
94
95 /**
96 * hb_set_destroy: (skip)
97 * @set: A set
98 *
99 * Decreases the reference count on a set. When
100 * the reference count reaches zero, the set is
101 * destroyed, freeing all memory.
102 *
103 * Since: 0.9.2
104 **/
105 void
hb_set_destroy(hb_set_t * set)106 hb_set_destroy (hb_set_t *set)
107 {
108 if (!hb_object_destroy (set)) return;
109
110 set->fini_shallow ();
111
112 free (set);
113 }
114
115 /**
116 * hb_set_set_user_data: (skip)
117 * @set: A set
118 * @key: The user-data key to set
119 * @data: A pointer to the user data to set
120 * @destroy: (nullable): A callback to call when @data is not needed anymore
121 * @replace: Whether to replace an existing data with the same key
122 *
123 * Attaches a user-data key/data pair to the specified set.
124 *
125 * Return value: %true if success, %false otherwise
126 *
127 * Since: 0.9.2
128 **/
129 hb_bool_t
hb_set_set_user_data(hb_set_t * set,hb_user_data_key_t * key,void * data,hb_destroy_func_t destroy,hb_bool_t replace)130 hb_set_set_user_data (hb_set_t *set,
131 hb_user_data_key_t *key,
132 void * data,
133 hb_destroy_func_t destroy,
134 hb_bool_t replace)
135 {
136 return hb_object_set_user_data (set, key, data, destroy, replace);
137 }
138
139 /**
140 * hb_set_get_user_data: (skip)
141 * @set: A set
142 * @key: The user-data key to query
143 *
144 * Fetches the user data associated with the specified key,
145 * attached to the specified set.
146 *
147 * Return value: (transfer none): A pointer to the user data
148 *
149 * Since: 0.9.2
150 **/
151 void *
hb_set_get_user_data(hb_set_t * set,hb_user_data_key_t * key)152 hb_set_get_user_data (hb_set_t *set,
153 hb_user_data_key_t *key)
154 {
155 return hb_object_get_user_data (set, key);
156 }
157
158
159 /**
160 * hb_set_allocation_successful:
161 * @set: A set
162 *
163 * Tests whether memory allocation for a set was successful.
164 *
165 * Return value: %true if allocation succeeded, %false otherwise
166 *
167 * Since: 0.9.2
168 **/
169 hb_bool_t
hb_set_allocation_successful(const hb_set_t * set)170 hb_set_allocation_successful (const hb_set_t *set)
171 {
172 return set->successful;
173 }
174
175 /**
176 * hb_set_clear:
177 * @set: A set
178 *
179 * Clears out the contents of a set.
180 *
181 * Since: 0.9.2
182 **/
183 void
hb_set_clear(hb_set_t * set)184 hb_set_clear (hb_set_t *set)
185 {
186 if (unlikely (hb_object_is_immutable (set)))
187 return;
188
189 set->clear ();
190 }
191
192 /**
193 * hb_set_is_empty:
194 * @set: a set.
195 *
196 * Tests whether a set is empty (contains no elements).
197 *
198 * Return value: %true if @set is empty
199 *
200 * Since: 0.9.7
201 **/
202 hb_bool_t
hb_set_is_empty(const hb_set_t * set)203 hb_set_is_empty (const hb_set_t *set)
204 {
205 return set->is_empty ();
206 }
207
208 /**
209 * hb_set_has:
210 * @set: A set
211 * @codepoint: The element to query
212 *
213 * Tests whether @codepoint belongs to @set.
214 *
215 * Return value: %true if @codepoint is in @set, %false otherwise
216 *
217 * Since: 0.9.2
218 **/
219 hb_bool_t
hb_set_has(const hb_set_t * set,hb_codepoint_t codepoint)220 hb_set_has (const hb_set_t *set,
221 hb_codepoint_t codepoint)
222 {
223 return set->has (codepoint);
224 }
225
226 /**
227 * hb_set_add:
228 * @set: A set
229 * @codepoint: The element to add to @set
230 *
231 * Adds @codepoint to @set.
232 *
233 * Since: 0.9.2
234 **/
235 void
hb_set_add(hb_set_t * set,hb_codepoint_t codepoint)236 hb_set_add (hb_set_t *set,
237 hb_codepoint_t codepoint)
238 {
239 set->add (codepoint);
240 }
241
242 /**
243 * hb_set_add_range:
244 * @set: A set
245 * @first: The first element to add to @set
246 * @last: The final element to add to @set
247 *
248 * Adds all of the elements from @first to @last
249 * (inclusive) to @set.
250 *
251 * Since: 0.9.7
252 **/
253 void
hb_set_add_range(hb_set_t * set,hb_codepoint_t first,hb_codepoint_t last)254 hb_set_add_range (hb_set_t *set,
255 hb_codepoint_t first,
256 hb_codepoint_t last)
257 {
258 set->add_range (first, last);
259 }
260
261 /**
262 * hb_set_del:
263 * @set: A set
264 * @codepoint: Removes @codepoint from @set
265 *
266 * Removes @codepoint from @set.
267 *
268 * Since: 0.9.2
269 **/
270 void
hb_set_del(hb_set_t * set,hb_codepoint_t codepoint)271 hb_set_del (hb_set_t *set,
272 hb_codepoint_t codepoint)
273 {
274 set->del (codepoint);
275 }
276
277 /**
278 * hb_set_del_range:
279 * @set: A set
280 * @first: The first element to remove from @set
281 * @last: The final element to remove from @set
282 *
283 * Removes all of the elements from @first to @last
284 * (inclusive) from @set.
285 *
286 * Since: 0.9.7
287 **/
288 void
hb_set_del_range(hb_set_t * set,hb_codepoint_t first,hb_codepoint_t last)289 hb_set_del_range (hb_set_t *set,
290 hb_codepoint_t first,
291 hb_codepoint_t last)
292 {
293 set->del_range (first, last);
294 }
295
296 /**
297 * hb_set_is_equal:
298 * @set: A set
299 * @other: Another set
300 *
301 * Tests whether @set and @other are equal (contain the same
302 * elements).
303 *
304 * Return value: %true if the two sets are equal, %false otherwise.
305 *
306 * Since: 0.9.7
307 **/
308 hb_bool_t
hb_set_is_equal(const hb_set_t * set,const hb_set_t * other)309 hb_set_is_equal (const hb_set_t *set,
310 const hb_set_t *other)
311 {
312 return set->is_equal (other);
313 }
314
315 /**
316 * hb_set_is_subset:
317 * @set: A set
318 * @larger_set: Another set
319 *
320 * Tests whether @set is a subset of @larger_set.
321 *
322 * Return value: %true if the @set is a subset of (or equal to) @larger_set, %false otherwise.
323 *
324 * Since: 1.8.1
325 **/
326 hb_bool_t
hb_set_is_subset(const hb_set_t * set,const hb_set_t * larger_set)327 hb_set_is_subset (const hb_set_t *set,
328 const hb_set_t *larger_set)
329 {
330 return set->is_subset (larger_set);
331 }
332
333 /**
334 * hb_set_set:
335 * @set: A set
336 * @other: Another set
337 *
338 * Makes the contents of @set equal to the contents of @other.
339 *
340 * Since: 0.9.2
341 **/
342 void
hb_set_set(hb_set_t * set,const hb_set_t * other)343 hb_set_set (hb_set_t *set,
344 const hb_set_t *other)
345 {
346 set->set (other);
347 }
348
349 /**
350 * hb_set_union:
351 * @set: A set
352 * @other: Another set
353 *
354 * Makes @set the union of @set and @other.
355 *
356 * Since: 0.9.2
357 **/
358 void
hb_set_union(hb_set_t * set,const hb_set_t * other)359 hb_set_union (hb_set_t *set,
360 const hb_set_t *other)
361 {
362 set->union_ (other);
363 }
364
365 /**
366 * hb_set_intersect:
367 * @set: A set
368 * @other: Another set
369 *
370 * Makes @set the intersection of @set and @other.
371 *
372 * Since: 0.9.2
373 **/
374 void
hb_set_intersect(hb_set_t * set,const hb_set_t * other)375 hb_set_intersect (hb_set_t *set,
376 const hb_set_t *other)
377 {
378 set->intersect (other);
379 }
380
381 /**
382 * hb_set_subtract:
383 * @set: A set
384 * @other: Another set
385 *
386 * Subtracts the contents of @other from @set.
387 *
388 * Since: 0.9.2
389 **/
390 void
hb_set_subtract(hb_set_t * set,const hb_set_t * other)391 hb_set_subtract (hb_set_t *set,
392 const hb_set_t *other)
393 {
394 set->subtract (other);
395 }
396
397 /**
398 * hb_set_symmetric_difference:
399 * @set: A set
400 * @other: Another set
401 *
402 * Makes @set the symmetric difference of @set
403 * and @other.
404 *
405 * Since: 0.9.2
406 **/
407 void
hb_set_symmetric_difference(hb_set_t * set,const hb_set_t * other)408 hb_set_symmetric_difference (hb_set_t *set,
409 const hb_set_t *other)
410 {
411 set->symmetric_difference (other);
412 }
413
414 #ifndef HB_DISABLE_DEPRECATED
415 /**
416 * hb_set_invert:
417 * @set: A set
418 *
419 * Inverts the contents of @set.
420 *
421 * Since: 0.9.10
422 *
423 * Deprecated: 1.6.1
424 **/
425 void
hb_set_invert(hb_set_t * set HB_UNUSED)426 hb_set_invert (hb_set_t *set HB_UNUSED)
427 {
428 }
429 #endif
430
431 /**
432 * hb_set_get_population:
433 * @set: A set
434 *
435 * Returns the number of elements in the set.
436 *
437 * Return value: The population of @set
438 *
439 * Since: 0.9.7
440 **/
441 unsigned int
hb_set_get_population(const hb_set_t * set)442 hb_set_get_population (const hb_set_t *set)
443 {
444 return set->get_population ();
445 }
446
447 /**
448 * hb_set_get_min:
449 * @set: A set
450 *
451 * Finds the smallest element in the set.
452 *
453 * Return value: minimum of @set, or #HB_SET_VALUE_INVALID if @set is empty.
454 *
455 * Since: 0.9.7
456 **/
457 hb_codepoint_t
hb_set_get_min(const hb_set_t * set)458 hb_set_get_min (const hb_set_t *set)
459 {
460 return set->get_min ();
461 }
462
463 /**
464 * hb_set_get_max:
465 * @set: A set
466 *
467 * Finds the largest element in the set.
468 *
469 * Return value: maximum of @set, or #HB_SET_VALUE_INVALID if @set is empty.
470 *
471 * Since: 0.9.7
472 **/
473 hb_codepoint_t
hb_set_get_max(const hb_set_t * set)474 hb_set_get_max (const hb_set_t *set)
475 {
476 return set->get_max ();
477 }
478
479 /**
480 * hb_set_next:
481 * @set: A set
482 * @codepoint: (inout): Input = Code point to query
483 * Output = Code point retrieved
484 *
485 * Fetches the next element in @set that is greater than current value of @codepoint.
486 *
487 * Set @codepoint to #HB_SET_VALUE_INVALID to get started.
488 *
489 * Return value: %true if there was a next value, %false otherwise
490 *
491 * Since: 0.9.2
492 **/
493 hb_bool_t
hb_set_next(const hb_set_t * set,hb_codepoint_t * codepoint)494 hb_set_next (const hb_set_t *set,
495 hb_codepoint_t *codepoint)
496 {
497 return set->next (codepoint);
498 }
499
500 /**
501 * hb_set_previous:
502 * @set: A set
503 * @codepoint: (inout): Input = Code point to query
504 * Output = Code point retrieved
505 *
506 * Fetches the previous element in @set that is lower than current value of @codepoint.
507 *
508 * Set @codepoint to #HB_SET_VALUE_INVALID to get started.
509 *
510 * Return value: %true if there was a previous value, %false otherwise
511 *
512 * Since: 1.8.0
513 **/
514 hb_bool_t
hb_set_previous(const hb_set_t * set,hb_codepoint_t * codepoint)515 hb_set_previous (const hb_set_t *set,
516 hb_codepoint_t *codepoint)
517 {
518 return set->previous (codepoint);
519 }
520
521 /**
522 * hb_set_next_range:
523 * @set: A set
524 * @first: (out): The first code point in the range
525 * @last: (inout): Input = The current last code point in the range
526 * Output = The last code point in the range
527 *
528 * Fetches the next consecutive range of elements in @set that
529 * are greater than current value of @last.
530 *
531 * Set @last to #HB_SET_VALUE_INVALID to get started.
532 *
533 * Return value: %true if there was a next range, %false otherwise
534 *
535 * Since: 0.9.7
536 **/
537 hb_bool_t
hb_set_next_range(const hb_set_t * set,hb_codepoint_t * first,hb_codepoint_t * last)538 hb_set_next_range (const hb_set_t *set,
539 hb_codepoint_t *first,
540 hb_codepoint_t *last)
541 {
542 return set->next_range (first, last);
543 }
544
545 /**
546 * hb_set_previous_range:
547 * @set: A set
548 * @first: (inout): Input = The current first code point in the range
549 * Output = The first code point in the range
550 * @last: (out): The last code point in the range
551 *
552 * Fetches the previous consecutive range of elements in @set that
553 * are greater than current value of @last.
554 *
555 * Set @first to #HB_SET_VALUE_INVALID to get started.
556 *
557 * Return value: %true if there was a previous range, %false otherwise
558 *
559 * Since: 1.8.0
560 **/
561 hb_bool_t
hb_set_previous_range(const hb_set_t * set,hb_codepoint_t * first,hb_codepoint_t * last)562 hb_set_previous_range (const hb_set_t *set,
563 hb_codepoint_t *first,
564 hb_codepoint_t *last)
565 {
566 return set->previous_range (first, last);
567 }
568