+//----------------------------------------------------------------
+// Inclusions list
+//----------------------------------------------------------------
+
+// USetAdder implementation
+// Does not use uset.h to reduce code dependencies
+static void U_CALLCONV
+_set_add(USet *set, UChar32 c) {
+ ((UnicodeSet *)set)->add(c);
+}
+
+static void U_CALLCONV
+_set_addRange(USet *set, UChar32 start, UChar32 end) {
+ ((UnicodeSet *)set)->add(start, end);
+}
+
+static void U_CALLCONV
+_set_addString(USet *set, const UChar *str, int32_t length) {
+ ((UnicodeSet *)set)->add(UnicodeString((UBool)(length<0), str, length));
+}
+
+/**
+ * Cleanup function for UnicodeSet
+ */
+static UBool U_CALLCONV uset_cleanup(void) {
+ int32_t i;
+
+ for(i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
+ if (INCLUSIONS[i] != NULL) {
+ delete INCLUSIONS[i];
+ INCLUSIONS[i] = NULL;
+ }
+ }
+
+ return TRUE;
+}
+
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+/*
+Reduce excessive reallocation, and make it easier to detect initialization
+problems.
+Usually you don't see smaller sets than this for Unicode 5.0.
+*/
+#define DEFAULT_INCLUSION_CAPACITY 3072
+
+const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
+ UBool needInit;
+ UMTX_CHECK(NULL, (INCLUSIONS[src] == NULL), needInit);
+ if (needInit) {
+ UnicodeSet* incl = new UnicodeSet();
+ USetAdder sa = {
+ (USet *)incl,
+ _set_add,
+ _set_addRange,
+ _set_addString,
+ NULL, // don't need remove()
+ NULL // don't need removeRange()
+ };
+ incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
+ if (incl != NULL) {
+ switch(src) {
+ case UPROPS_SRC_CHAR:
+ uchar_addPropertyStarts(&sa, &status);
+ break;
+ case UPROPS_SRC_PROPSVEC:
+ upropsvec_addPropertyStarts(&sa, &status);
+ break;
+ case UPROPS_SRC_CHAR_AND_PROPSVEC:
+ uchar_addPropertyStarts(&sa, &status);
+ upropsvec_addPropertyStarts(&sa, &status);
+ break;
+ case UPROPS_SRC_HST:
+ uhst_addPropertyStarts(&sa, &status);
+ break;
+#if !UCONFIG_NO_NORMALIZATION
+ case UPROPS_SRC_NORM:
+ unorm_addPropertyStarts(&sa, &status);
+ break;
+#endif
+ case UPROPS_SRC_CASE:
+ ucase_addPropertyStarts(ucase_getSingleton(&status), &sa, &status);
+ break;
+ case UPROPS_SRC_BIDI:
+ ubidi_addPropertyStarts(ubidi_getSingleton(&status), &sa, &status);
+ break;
+ default:
+ status = U_INTERNAL_PROGRAM_ERROR;
+ break;
+ }
+ if (U_SUCCESS(status)) {
+ // Compact for caching
+ incl->compact();
+ umtx_lock(NULL);
+ if (INCLUSIONS[src] == NULL) {
+ INCLUSIONS[src] = incl;
+ incl = NULL;
+ ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
+ }
+ umtx_unlock(NULL);
+ }
+ delete incl;
+ } else {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ }
+ return INCLUSIONS[src];
+}
+