Coverage Report

Created: 2025-06-24 06:54

/src/icu/icu4c/source/common/uset.cpp
Line
Count
Source (jump to first uncovered line)
1
// © 2016 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
/*
4
*******************************************************************************
5
*
6
*   Copyright (C) 2002-2011, International Business Machines
7
*   Corporation and others.  All Rights Reserved.
8
*
9
*******************************************************************************
10
*   file name:  uset.cpp
11
*   encoding:   UTF-8
12
*   tab size:   8 (not used)
13
*   indentation:4
14
*
15
*   created on: 2002mar07
16
*   created by: Markus W. Scherer
17
*
18
*   There are functions to efficiently serialize a USet into an array of uint16_t
19
*   and functions to use such a serialized form efficiently without
20
*   instantiating a new USet.
21
*/
22
23
#include "unicode/utypes.h"
24
#include "unicode/char16ptr.h"
25
#include "unicode/uobject.h"
26
#include "unicode/uset.h"
27
#include "unicode/uniset.h"
28
#include "cmemory.h"
29
#include "unicode/ustring.h"
30
#include "unicode/parsepos.h"
31
32
U_NAMESPACE_USE
33
34
U_CAPI USet* U_EXPORT2
35
0
uset_openEmpty() {
36
0
    return (USet*) new UnicodeSet();
37
0
}
38
39
U_CAPI USet* U_EXPORT2
40
0
uset_open(UChar32 start, UChar32 end) {
41
0
    return (USet*) new UnicodeSet(start, end);
42
0
}
43
44
U_CAPI void U_EXPORT2
45
0
uset_close(USet* set) {
46
0
    delete (UnicodeSet*) set;
47
0
}
48
49
U_CAPI USet * U_EXPORT2
50
0
uset_clone(const USet *set) {
51
0
    return (USet*) (((UnicodeSet*) set)->UnicodeSet::clone());
52
0
}
53
54
U_CAPI UBool U_EXPORT2
55
0
uset_isFrozen(const USet *set) {
56
0
    return ((UnicodeSet*) set)->UnicodeSet::isFrozen();
57
0
}
58
59
U_CAPI void U_EXPORT2
60
0
uset_freeze(USet *set) {
61
0
    ((UnicodeSet*) set)->UnicodeSet::freeze();
62
0
}
63
64
U_CAPI USet * U_EXPORT2
65
0
uset_cloneAsThawed(const USet *set) {
66
0
    return (USet*) (((UnicodeSet*) set)->UnicodeSet::cloneAsThawed());
67
0
}
68
69
U_CAPI void U_EXPORT2
70
uset_set(USet* set,
71
0
     UChar32 start, UChar32 end) {
72
0
    ((UnicodeSet*) set)->UnicodeSet::set(start, end);
73
0
}
74
75
U_CAPI void U_EXPORT2
76
0
uset_addAll(USet* set, const USet *additionalSet) {
77
0
    ((UnicodeSet*) set)->UnicodeSet::addAll(*((const UnicodeSet*)additionalSet));
78
0
}
79
80
U_CAPI void U_EXPORT2
81
0
uset_add(USet* set, UChar32 c) {
82
0
    ((UnicodeSet*) set)->UnicodeSet::add(c);
83
0
}
84
85
U_CAPI void U_EXPORT2
86
0
uset_addRange(USet* set, UChar32 start, UChar32 end) {
87
0
    ((UnicodeSet*) set)->UnicodeSet::add(start, end);    
88
0
}
89
90
U_CAPI void U_EXPORT2
91
0
uset_addString(USet* set, const char16_t* str, int32_t strLen) {
92
    // UnicodeString handles -1 for strLen
93
0
    UnicodeString s(strLen<0, str, strLen);
94
0
    ((UnicodeSet*) set)->UnicodeSet::add(s);
95
0
}
96
97
U_CAPI void U_EXPORT2
98
0
uset_addAllCodePoints(USet* set, const char16_t *str, int32_t strLen) {
99
    // UnicodeString handles -1 for strLen
100
0
    UnicodeString s(str, strLen);
101
0
    ((UnicodeSet*) set)->UnicodeSet::addAll(s);
102
0
}
103
104
U_CAPI void U_EXPORT2
105
0
uset_remove(USet* set, UChar32 c) {
106
0
    ((UnicodeSet*) set)->UnicodeSet::remove(c);
107
0
}
108
109
U_CAPI void U_EXPORT2
110
0
uset_removeRange(USet* set, UChar32 start, UChar32 end) {
111
0
    ((UnicodeSet*) set)->UnicodeSet::remove(start, end);
112
0
}
113
114
U_CAPI void U_EXPORT2
115
0
uset_removeString(USet* set, const char16_t* str, int32_t strLen) {
116
0
    UnicodeString s(strLen==-1, str, strLen);
117
0
    ((UnicodeSet*) set)->UnicodeSet::remove(s);
118
0
}
119
120
U_CAPI void U_EXPORT2
121
0
uset_removeAllCodePoints(USet *set, const char16_t *str, int32_t length) {
122
0
    UnicodeString s(length==-1, str, length);
123
0
    ((UnicodeSet*) set)->UnicodeSet::removeAll(s);
124
0
}
125
126
U_CAPI void U_EXPORT2
127
0
uset_removeAll(USet* set, const USet* remove) {
128
0
    ((UnicodeSet*) set)->UnicodeSet::removeAll(*(const UnicodeSet*)remove);
129
0
}
130
131
U_CAPI void U_EXPORT2
132
0
uset_retain(USet* set, UChar32 start, UChar32 end) {
133
0
    ((UnicodeSet*) set)->UnicodeSet::retain(start, end);
134
0
}
135
136
U_CAPI void U_EXPORT2
137
0
uset_retainString(USet *set, const char16_t *str, int32_t length) {
138
0
    UnicodeString s(length==-1, str, length);
139
0
    ((UnicodeSet*) set)->UnicodeSet::retain(s);
140
0
}
141
142
U_CAPI void U_EXPORT2
143
0
uset_retainAllCodePoints(USet *set, const char16_t *str, int32_t length) {
144
0
    UnicodeString s(length==-1, str, length);
145
0
    ((UnicodeSet*) set)->UnicodeSet::retainAll(s);
146
0
}
147
148
U_CAPI void U_EXPORT2
149
0
uset_retainAll(USet* set, const USet* retain) {
150
0
    ((UnicodeSet*) set)->UnicodeSet::retainAll(*(const UnicodeSet*)retain);
151
0
}
152
153
U_CAPI void U_EXPORT2
154
0
uset_compact(USet* set) {
155
0
    ((UnicodeSet*) set)->UnicodeSet::compact();
156
0
}
157
158
U_CAPI void U_EXPORT2
159
0
uset_complement(USet* set) {
160
0
    ((UnicodeSet*) set)->UnicodeSet::complement();
161
0
}
162
163
U_CAPI void U_EXPORT2
164
0
uset_complementRange(USet *set, UChar32 start, UChar32 end) {
165
0
    ((UnicodeSet*) set)->UnicodeSet::complement(start, end);
166
0
}
167
168
U_CAPI void U_EXPORT2
169
0
uset_complementString(USet *set, const char16_t *str, int32_t length) {
170
0
    UnicodeString s(length==-1, str, length);
171
0
    ((UnicodeSet*) set)->UnicodeSet::complement(s);
172
0
}
173
174
U_CAPI void U_EXPORT2
175
0
uset_complementAllCodePoints(USet *set, const char16_t *str, int32_t length) {
176
0
    UnicodeString s(length==-1, str, length);
177
0
    ((UnicodeSet*) set)->UnicodeSet::complementAll(s);
178
0
}
179
180
U_CAPI void U_EXPORT2
181
0
uset_complementAll(USet* set, const USet* complement) {
182
0
    ((UnicodeSet*) set)->UnicodeSet::complementAll(*(const UnicodeSet*)complement);
183
0
}
184
185
U_CAPI void U_EXPORT2
186
0
uset_clear(USet* set) {
187
0
    ((UnicodeSet*) set)->UnicodeSet::clear();
188
0
}
189
190
U_CAPI void U_EXPORT2
191
0
uset_removeAllStrings(USet* set) {
192
0
    ((UnicodeSet*) set)->UnicodeSet::removeAllStrings();
193
0
}
194
195
U_CAPI UBool U_EXPORT2
196
0
uset_isEmpty(const USet* set) {
197
0
    return ((const UnicodeSet*) set)->UnicodeSet::isEmpty();
198
0
}
199
200
U_CAPI UBool U_EXPORT2
201
0
uset_hasStrings(const USet* set) {
202
0
    return ((const UnicodeSet*) set)->UnicodeSet::hasStrings();
203
0
}
204
205
U_CAPI UBool U_EXPORT2
206
0
uset_contains(const USet* set, UChar32 c) {
207
0
    return ((const UnicodeSet*) set)->UnicodeSet::contains(c);
208
0
}
209
210
U_CAPI UBool U_EXPORT2
211
0
uset_containsRange(const USet* set, UChar32 start, UChar32 end) {
212
0
    return ((const UnicodeSet*) set)->UnicodeSet::contains(start, end);
213
0
}
214
215
U_CAPI UBool U_EXPORT2
216
0
uset_containsString(const USet* set, const char16_t* str, int32_t strLen) {
217
0
    UnicodeString s(strLen==-1, str, strLen);
218
0
    return ((const UnicodeSet*) set)->UnicodeSet::contains(s);
219
0
}
220
221
U_CAPI UBool U_EXPORT2
222
0
uset_containsAll(const USet* set1, const USet* set2) {
223
0
    return ((const UnicodeSet*) set1)->UnicodeSet::containsAll(* (const UnicodeSet*) set2);
224
0
}
225
226
U_CAPI UBool U_EXPORT2
227
0
uset_containsAllCodePoints(const USet* set, const char16_t *str, int32_t strLen) {
228
    // Create a string alias, since nothing is being added to the set.
229
0
    UnicodeString s(strLen==-1, str, strLen);
230
0
    return ((const UnicodeSet*) set)->UnicodeSet::containsAll(s);
231
0
}
232
233
U_CAPI UBool U_EXPORT2
234
0
uset_containsNone(const USet* set1, const USet* set2) {
235
0
    return ((const UnicodeSet*) set1)->UnicodeSet::containsNone(* (const UnicodeSet*) set2);
236
0
}
237
238
U_CAPI UBool U_EXPORT2
239
0
uset_containsSome(const USet* set1, const USet* set2) {
240
0
    return ((const UnicodeSet*) set1)->UnicodeSet::containsSome(* (const UnicodeSet*) set2);
241
0
}
242
243
U_CAPI int32_t U_EXPORT2
244
0
uset_span(const USet *set, const char16_t *s, int32_t length, USetSpanCondition spanCondition) {
245
0
    return ((UnicodeSet*) set)->UnicodeSet::span(s, length, spanCondition);
246
0
}
247
248
U_CAPI int32_t U_EXPORT2
249
0
uset_spanBack(const USet *set, const char16_t *s, int32_t length, USetSpanCondition spanCondition) {
250
0
    return ((UnicodeSet*) set)->UnicodeSet::spanBack(s, length, spanCondition);
251
0
}
252
253
U_CAPI int32_t U_EXPORT2
254
0
uset_spanUTF8(const USet *set, const char *s, int32_t length, USetSpanCondition spanCondition) {
255
0
    return ((UnicodeSet*) set)->UnicodeSet::spanUTF8(s, length, spanCondition);
256
0
}
257
258
U_CAPI int32_t U_EXPORT2
259
0
uset_spanBackUTF8(const USet *set, const char *s, int32_t length, USetSpanCondition spanCondition) {
260
0
    return ((UnicodeSet*) set)->UnicodeSet::spanBackUTF8(s, length, spanCondition);
261
0
}
262
263
U_CAPI UBool U_EXPORT2
264
0
uset_equals(const USet* set1, const USet* set2) {
265
0
    return *(const UnicodeSet*)set1 == *(const UnicodeSet*)set2;
266
0
}
267
268
U_CAPI int32_t U_EXPORT2
269
0
uset_indexOf(const USet* set, UChar32 c) {
270
0
    return ((UnicodeSet*) set)->UnicodeSet::indexOf(c);
271
0
}
272
273
U_CAPI UChar32 U_EXPORT2
274
0
uset_charAt(const USet* set, int32_t index) {
275
0
    return ((UnicodeSet*) set)->UnicodeSet::charAt(index);
276
0
}
277
278
U_CAPI int32_t U_EXPORT2
279
0
uset_size(const USet* set) {
280
0
    return ((const UnicodeSet*) set)->UnicodeSet::size();
281
0
}
282
283
U_NAMESPACE_BEGIN
284
/**
285
 * This class only exists to provide access to the UnicodeSet private
286
 * USet support API.  Declaring a class a friend is more portable than
287
 * trying to declare extern "C" functions as friends.
288
 */
289
class USetAccess /* not : public UObject because all methods are static */ {
290
public:
291
    /* Try to have the compiler inline these*/
292
0
    inline static int32_t getStringCount(const UnicodeSet& set) {
293
0
        return set.stringsSize();
294
0
    }
295
    inline static const UnicodeString* getString(const UnicodeSet& set,
296
0
                                                 int32_t i) {
297
0
        return set.getString(i);
298
0
    }
299
private:
300
    /* do not instantiate*/
301
    USetAccess();
302
};
303
U_NAMESPACE_END
304
305
U_CAPI int32_t U_EXPORT2
306
0
uset_getRangeCount(const USet *set) {
307
0
    return ((const UnicodeSet *)set)->UnicodeSet::getRangeCount();
308
0
}
309
310
U_CAPI int32_t U_EXPORT2
311
0
uset_getStringCount(const USet *uset) {
312
0
    const UnicodeSet &set = *(const UnicodeSet *)uset;
313
0
    return USetAccess::getStringCount(set);
314
0
}
315
316
U_CAPI int32_t U_EXPORT2
317
0
uset_getItemCount(const USet* uset) {
318
0
    const UnicodeSet& set = *(const UnicodeSet*)uset;
319
0
    return set.getRangeCount() + USetAccess::getStringCount(set);
320
0
}
321
322
U_CAPI const UChar* U_EXPORT2
323
0
uset_getString(const USet *uset, int32_t index, int32_t *pLength) {
324
0
    if (pLength == nullptr) { return nullptr; }
325
0
    const UnicodeSet &set = *(const UnicodeSet *)uset;
326
0
    int32_t count = USetAccess::getStringCount(set);
327
0
    if (index < 0 || count <= index) {
328
0
        *pLength = 0;
329
0
        return nullptr;
330
0
    }
331
0
    const UnicodeString *s = USetAccess::getString(set, index);
332
0
    *pLength = s->length();
333
0
    return toUCharPtr(s->getBuffer());
334
0
}
335
336
U_CAPI int32_t U_EXPORT2
337
uset_getItem(const USet* uset, int32_t itemIndex,
338
             UChar32* start, UChar32* end,
339
             char16_t* str, int32_t strCapacity,
340
0
             UErrorCode* ec) {
341
0
    if (U_FAILURE(*ec)) return 0;
342
0
    const UnicodeSet& set = *(const UnicodeSet*)uset;
343
0
    int32_t rangeCount;
344
345
0
    if (itemIndex < 0) {
346
0
        *ec = U_ILLEGAL_ARGUMENT_ERROR;
347
0
        return -1;
348
0
    } else if (itemIndex < (rangeCount = set.getRangeCount())) {
349
0
        *start = set.getRangeStart(itemIndex);
350
0
        *end = set.getRangeEnd(itemIndex);
351
0
        return 0;
352
0
    } else {
353
0
        itemIndex -= rangeCount;
354
0
        if (itemIndex < USetAccess::getStringCount(set)) {
355
0
            const UnicodeString* s = USetAccess::getString(set, itemIndex);
356
0
            return s->extract(str, strCapacity, *ec);
357
0
        } else {
358
0
            *ec = U_INDEX_OUTOFBOUNDS_ERROR;
359
0
            return -1;
360
0
        }
361
0
    }
362
0
}
363
364
//U_CAPI UBool U_EXPORT2
365
//uset_getRange(const USet* set, int32_t rangeIndex,
366
//              UChar32* pStart, UChar32* pEnd) {
367
//    if ((uint32_t) rangeIndex >= (uint32_t) uset_getRangeCount(set)) {
368
//        return false;
369
//    }
370
//    const UnicodeSet* us = (const UnicodeSet*) set;
371
//    *pStart = us->getRangeStart(rangeIndex);
372
//    *pEnd = us->getRangeEnd(rangeIndex);
373
//    return true;
374
//}
375
376
/*
377
 * Serialize a USet into 16-bit units.
378
 * Store BMP code points as themselves with one 16-bit unit each.
379
 *
380
 * Important: the code points in the array are in ascending order,
381
 * therefore all BMP code points precede all supplementary code points.
382
 *
383
 * Store each supplementary code point in 2 16-bit units,
384
 * simply with higher-then-lower 16-bit halves.
385
 *
386
 * Precede the entire list with the length.
387
 * If there are supplementary code points, then set bit 15 in the length
388
 * and add the bmpLength between it and the array.
389
 *
390
 * In other words:
391
 * - all BMP:            (length=bmpLength) BMP, .., BMP
392
 * - some supplementary: (length|0x8000) (bmpLength<length) BMP, .., BMP, supp-high, supp-low, ..
393
 */
394
U_CAPI int32_t U_EXPORT2
395
0
uset_serialize(const USet* set, uint16_t* dest, int32_t destCapacity, UErrorCode* ec) {
396
0
    if (ec==nullptr || U_FAILURE(*ec)) {
397
0
        return 0;
398
0
    }
399
400
0
    return ((const UnicodeSet*) set)->UnicodeSet::serialize(dest, destCapacity,* ec);
401
0
}
402
403
U_CAPI UBool U_EXPORT2
404
66
uset_getSerializedSet(USerializedSet* fillSet, const uint16_t* src, int32_t srcLength) {
405
66
    int32_t length;
406
407
66
    if(fillSet==nullptr) {
408
0
        return false;
409
0
    }
410
66
    if(src==nullptr || srcLength<=0) {
411
0
        fillSet->length=fillSet->bmpLength=0;
412
0
        return false;
413
0
    }
414
415
66
    length=*src++;
416
66
    if(length&0x8000) {
417
        /* there are supplementary values */
418
7
        length&=0x7fff;
419
7
        if(srcLength<(2+length)) {
420
0
            fillSet->length=fillSet->bmpLength=0;
421
0
            return false;
422
0
        }
423
7
        fillSet->bmpLength=*src++;
424
59
    } else {
425
        /* only BMP values */
426
59
        if(srcLength<(1+length)) {
427
0
            fillSet->length=fillSet->bmpLength=0;
428
0
            return false;
429
0
        }
430
59
        fillSet->bmpLength=length;
431
59
    }
432
66
    fillSet->array=src;
433
66
    fillSet->length=length;
434
66
    return true;
435
66
}
436
437
U_CAPI void U_EXPORT2
438
0
uset_setSerializedToOne(USerializedSet* fillSet, UChar32 c) {
439
0
    if(fillSet==nullptr || (uint32_t)c>0x10ffff) {
440
0
        return;
441
0
    }
442
443
0
    fillSet->array=fillSet->staticArray;
444
0
    if(c<0xffff) {
445
0
        fillSet->bmpLength=fillSet->length=2;
446
0
        fillSet->staticArray[0]=(uint16_t)c;
447
0
        fillSet->staticArray[1]=(uint16_t)c+1;
448
0
    } else if(c==0xffff) {
449
0
        fillSet->bmpLength=1;
450
0
        fillSet->length=3;
451
0
        fillSet->staticArray[0]=0xffff;
452
0
        fillSet->staticArray[1]=1;
453
0
        fillSet->staticArray[2]=0;
454
0
    } else if(c<0x10ffff) {
455
0
        fillSet->bmpLength=0;
456
0
        fillSet->length=4;
457
0
        fillSet->staticArray[0]=(uint16_t)(c>>16);
458
0
        fillSet->staticArray[1]=(uint16_t)c;
459
0
        ++c;
460
0
        fillSet->staticArray[2]=(uint16_t)(c>>16);
461
0
        fillSet->staticArray[3]=(uint16_t)c;
462
0
    } else /* c==0x10ffff */ {
463
0
        fillSet->bmpLength=0;
464
0
        fillSet->length=2;
465
0
        fillSet->staticArray[0]=0x10;
466
0
        fillSet->staticArray[1]=0xffff;
467
0
    }
468
0
}
469
470
U_CAPI UBool U_EXPORT2
471
0
uset_serializedContains(const USerializedSet* set, UChar32 c) {
472
0
    const uint16_t* array;
473
474
0
    if(set==nullptr || (uint32_t)c>0x10ffff) {
475
0
        return false;
476
0
    }
477
478
0
    array=set->array;
479
0
    if(c<=0xffff) {
480
        /* find c in the BMP part */
481
0
        int32_t lo = 0;
482
0
        int32_t hi = set->bmpLength-1;
483
0
        if (c < array[0]) {
484
0
            hi = 0;
485
0
        } else if (c < array[hi]) {
486
0
            for(;;) {
487
0
                int32_t i = (lo + hi) >> 1;
488
0
                if (i == lo) {
489
0
                    break;  // Done!
490
0
                } else if (c < array[i]) {
491
0
                    hi = i;
492
0
                } else {
493
0
                    lo = i;
494
0
                }
495
0
            }
496
0
        } else {
497
0
            hi += 1;
498
0
        }
499
0
        return hi&1;
500
0
    } else {
501
        /* find c in the supplementary part */
502
0
        uint16_t high=(uint16_t)(c>>16), low=(uint16_t)c;
503
0
        int32_t base = set->bmpLength;
504
0
        int32_t lo = 0;
505
0
        int32_t hi = set->length - 2 - base;
506
0
        if (high < array[base] || (high==array[base] && low<array[base+1])) {
507
0
            hi = 0;
508
0
        } else if (high < array[base+hi] || (high==array[base+hi] && low<array[base+hi+1])) {
509
0
            for (;;) {
510
0
                int32_t i = ((lo + hi) >> 1) & ~1;  // Guarantee even result
511
0
                int32_t iabs = i + base;
512
0
                if (i == lo) {
513
0
                    break;  // Done!
514
0
                } else if (high < array[iabs] || (high==array[iabs] && low<array[iabs+1])) {
515
0
                    hi = i;
516
0
                } else {
517
0
                    lo = i;
518
0
                }
519
0
            }
520
0
        } else {
521
0
            hi += 2;
522
0
        }
523
        /* count pairs of 16-bit units even per BMP and check if the number of pairs is odd */
524
0
        return ((hi+(base<<1))&2)!=0;
525
0
    }
526
0
}
527
528
U_CAPI int32_t U_EXPORT2
529
66
uset_getSerializedRangeCount(const USerializedSet* set) {
530
66
    if(set==nullptr) {
531
0
        return 0;
532
0
    }
533
534
66
    return (set->bmpLength+(set->length-set->bmpLength)/2+1)/2;
535
66
}
536
537
U_CAPI UBool U_EXPORT2
538
uset_getSerializedRange(const USerializedSet* set, int32_t rangeIndex,
539
1.75k
                        UChar32* pStart, UChar32* pEnd) {
540
1.75k
    const uint16_t* array;
541
1.75k
    int32_t bmpLength, length;
542
543
1.75k
    if(set==nullptr || rangeIndex<0 || pStart==nullptr || pEnd==nullptr) {
544
0
        return false;
545
0
    }
546
547
1.75k
    array=set->array;
548
1.75k
    length=set->length;
549
1.75k
    bmpLength=set->bmpLength;
550
551
1.75k
    rangeIndex*=2; /* address start/limit pairs */
552
1.75k
    if(rangeIndex<bmpLength) {
553
1.42k
        *pStart=array[rangeIndex++];
554
1.42k
        if(rangeIndex<bmpLength) {
555
1.42k
            *pEnd=array[rangeIndex]-1;
556
1.42k
        } else if(rangeIndex<length) {
557
0
            *pEnd=((((int32_t)array[rangeIndex])<<16)|array[rangeIndex+1])-1;
558
0
        } else {
559
0
            *pEnd=0x10ffff;
560
0
        }
561
1.42k
        return true;
562
1.42k
    } else {
563
328
        rangeIndex-=bmpLength;
564
328
        rangeIndex*=2; /* address pairs of pairs of units */
565
328
        length-=bmpLength;
566
328
        if(rangeIndex<length) {
567
328
            array+=bmpLength;
568
328
            *pStart=(((int32_t)array[rangeIndex])<<16)|array[rangeIndex+1];
569
328
            rangeIndex+=2;
570
328
            if(rangeIndex<length) {
571
328
                *pEnd=((((int32_t)array[rangeIndex])<<16)|array[rangeIndex+1])-1;
572
328
            } else {
573
0
                *pEnd=0x10ffff;
574
0
            }
575
328
            return true;
576
328
        } else {
577
0
            return false;
578
0
        }
579
328
    }
580
1.75k
}
581
582
// TODO The old, internal uset.c had an efficient uset_containsOne function.
583
// Returned the one and only code point, or else -1 or something.
584
// Consider adding such a function to both C and C++ UnicodeSet/uset.
585
// See tools/gennorm/store.c for usage, now usetContainsOne there.
586
587
// TODO Investigate incorporating this code into UnicodeSet to improve
588
// efficiency.
589
// ---
590
// #define USET_GROW_DELTA 20
591
// 
592
// static int32_t
593
// findChar(const UChar32* array, int32_t length, UChar32 c) {
594
//     int32_t i;
595
// 
596
//     /* check the last range limit first for more efficient appending */
597
//     if(length>0) {
598
//         if(c>=array[length-1]) {
599
//             return length;
600
//         }
601
// 
602
//         /* do not check the last range limit again in the loop below */
603
//         --length;
604
//     }
605
// 
606
//     for(i=0; i<length && c>=array[i]; ++i) {}
607
//     return i;
608
// }
609
// 
610
// static UBool
611
// addRemove(USet* set, UChar32 c, int32_t doRemove) {
612
//     int32_t i, length, more;
613
// 
614
//     if(set==nullptr || (uint32_t)c>0x10ffff) {
615
//         return false;
616
//     }
617
// 
618
//     length=set->length;
619
//     i=findChar(set->array, length, c);
620
//     if((i&1)^doRemove) {
621
//         /* c is already in the set */
622
//         return true;
623
//     }
624
// 
625
//     /* how many more array items do we need? */
626
//     if(i<length && (c+1)==set->array[i]) {
627
//         /* c is just before the following range, extend that in-place by one */
628
//         set->array[i]=c;
629
//         if(i>0) {
630
//             --i;
631
//             if(c==set->array[i]) {
632
//                 /* the previous range collapsed, remove it */
633
//                 set->length=length-=2;
634
//                 if(i<length) {
635
//                     uprv_memmove(set->array+i, set->array+i+2, (length-i)*4);
636
//                 }
637
//             }
638
//         }
639
//         return true;
640
//     } else if(i>0 && c==set->array[i-1]) {
641
//         /* c is just after the previous range, extend that in-place by one */
642
//         if(++c<=0x10ffff) {
643
//             set->array[i-1]=c;
644
//             if(i<length && c==set->array[i]) {
645
//                 /* the following range collapsed, remove it */
646
//                 --i;
647
//                 set->length=length-=2;
648
//                 if(i<length) {
649
//                     uprv_memmove(set->array+i, set->array+i+2, (length-i)*4);
650
//                 }
651
//             }
652
//         } else {
653
//             /* extend the previous range (had limit 0x10ffff) to the end of Unicode */
654
//             set->length=i-1;
655
//         }
656
//         return true;
657
//     } else if(i==length && c==0x10ffff) {
658
//         /* insert one range limit c */
659
//         more=1;
660
//     } else {
661
//         /* insert two range limits c, c+1 */
662
//         more=2;
663
//     }
664
// 
665
//     /* insert <more> range limits */
666
//     if(length+more>set->capacity) {
667
//         /* reallocate */
668
//         int32_t newCapacity=set->capacity+set->capacity/2+USET_GROW_DELTA;
669
//         UChar32* newArray=(UChar32* )uprv_malloc(newCapacity*4);
670
//         if(newArray==nullptr) {
671
//             return false;
672
//         }
673
//         set->capacity=newCapacity;
674
//         uprv_memcpy(newArray, set->array, length*4);
675
// 
676
//         if(set->array!=set->staticBuffer) {
677
//             uprv_free(set->array);
678
//         }
679
//         set->array=newArray;
680
//     }
681
// 
682
//     if(i<length) {
683
//         uprv_memmove(set->array+i+more, set->array+i, (length-i)*4);
684
//     }
685
//     set->array[i]=c;
686
//     if(more==2) {
687
//         set->array[i+1]=c+1;
688
//     }
689
//     set->length+=more;
690
// 
691
//     return true;
692
// }
693
// 
694
// U_CAPI UBool U_EXPORT2
695
// uset_add(USet* set, UChar32 c) {
696
//     return addRemove(set, c, 0);
697
// }
698
// 
699
// U_CAPI void U_EXPORT2
700
// uset_remove(USet* set, UChar32 c) {
701
//     addRemove(set, c, 1);
702
// }