diff --git a/icu4c/source/test/intltest/Makefile.in b/icu4c/source/test/intltest/Makefile.in
index 66956355c841..81ad55578072 100644
--- a/icu4c/source/test/intltest/Makefile.in
+++ b/icu4c/source/test/intltest/Makefile.in
@@ -75,7 +75,7 @@ numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \
static_unisets_test.o numfmtdatadriventest.o numbertest_range.o erarulestest.o \
formattedvaluetest.o formatted_string_builder_test.o numbertest_permutation.o \
units_data_test.o units_router_test.o units_test.o displayoptions_test.o \
-numbertest_simple.o uchar_type_build_test.o
+numbertest_simple.o uchar_type_build_test.o usetheaderonlytest.o
DEPS = $(OBJECTS:.o=.d)
diff --git a/icu4c/source/test/intltest/intltest.vcxproj b/icu4c/source/test/intltest/intltest.vcxproj
index 9e6480aa4e1b..b58b29b3d4e7 100644
--- a/icu4c/source/test/intltest/intltest.vcxproj
+++ b/icu4c/source/test/intltest/intltest.vcxproj
@@ -242,6 +242,7 @@
+
diff --git a/icu4c/source/test/intltest/intltest.vcxproj.filters b/icu4c/source/test/intltest/intltest.vcxproj.filters
index f3dca92d191c..d5c23d5e4cb5 100644
--- a/icu4c/source/test/intltest/intltest.vcxproj.filters
+++ b/icu4c/source/test/intltest/intltest.vcxproj.filters
@@ -571,9 +571,18 @@
configuration
-
-
-
+
+ formatting
+
+
+ formatting
+
+
+ formatting
+
+
+ misc
+
diff --git a/icu4c/source/test/intltest/itutil.cpp b/icu4c/source/test/intltest/itutil.cpp
index ec69e20bed0b..4585792126d6 100644
--- a/icu4c/source/test/intltest/itutil.cpp
+++ b/icu4c/source/test/intltest/itutil.cpp
@@ -35,6 +35,7 @@
#include "usettest.h"
extern IntlTest *createBytesTrieTest();
+extern IntlTest *createUSetHeaderOnlyTest();
extern IntlTest *createLocaleMatcherTest();
static IntlTest *createLocalPointerTest();
extern IntlTest *createUCharsTrieTest();
@@ -82,6 +83,7 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &
TESTCASE_AUTO_CLASS(LocaleBuilderTest);
TESTCASE_AUTO_CREATE_CLASS(LocaleMatcherTest);
TESTCASE_AUTO_CREATE_CLASS(UHashTest);
+ TESTCASE_AUTO_CREATE_CLASS(USetHeaderOnlyTest);
TESTCASE_AUTO_END;
}
diff --git a/icu4c/source/test/intltest/usetheaderonlytest.cpp b/icu4c/source/test/intltest/usetheaderonlytest.cpp
new file mode 100644
index 000000000000..38bc175c1746
--- /dev/null
+++ b/icu4c/source/test/intltest/usetheaderonlytest.cpp
@@ -0,0 +1,219 @@
+// © 2024 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+// usetheaderonlytest.cpp
+// created: 2024dec11 Markus W. Scherer
+
+#include
+
+// Test header-only ICU C++ APIs. Do not use other ICU C++ APIs.
+// Non-default configuration:
+#define U_SHOW_CPLUSPLUS_API 0
+// Default configuration:
+// #define U_SHOW_CPLUSPLUS_HEADER_API 1
+
+#include "unicode/utypes.h"
+#include "unicode/uset.h"
+#include "unicode/utf.h"
+#include "unicode/utf16.h"
+#include "intltest.h"
+
+class USetHeaderOnlyTest : public IntlTest {
+public:
+ USetHeaderOnlyTest() = default;
+
+ void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=nullptr) override;
+
+ void TestUSetCodePointIterator();
+ void TestUSetRangeIterator();
+ void TestUSetStringIterator();
+ void TestUSetElementIterator();
+};
+
+extern IntlTest *createUSetHeaderOnlyTest() {
+ return new USetHeaderOnlyTest();
+}
+
+void USetHeaderOnlyTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) {
+ if(exec) {
+ logln("TestSuite USetHeaderOnlyTest: ");
+ }
+ TESTCASE_AUTO_BEGIN;
+ TESTCASE_AUTO(TestUSetCodePointIterator);
+ TESTCASE_AUTO(TestUSetRangeIterator);
+ TESTCASE_AUTO(TestUSetStringIterator);
+ TESTCASE_AUTO(TestUSetElementIterator);
+ TESTCASE_AUTO_END;
+}
+
+std::u16string cpString(UChar32 c) {
+ if (U_IS_BMP(c)) {
+ return {static_cast(c)};
+ } else {
+ return {U16_LEAD(c), U16_TRAIL(c)};
+ }
+}
+
+void USetHeaderOnlyTest::TestUSetCodePointIterator() {
+ IcuTestErrorCode errorCode(*this, "TestUSetCodePointIterator");
+ using U_HEADER_NESTED_NAMESPACE::USetCodePoints;
+ LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴]", -1, errorCode));
+ std::u16string result;
+ for (UChar32 c : USetCodePoints(uset.getAlias())) {
+ // Commented-out sample code for pasting into the API docs.
+ // printf("uset.codePoint U+%04lx\n", (long)c);
+ result.append(u" ").append(cpString(c));
+ }
+ assertEquals(WHERE, u" a b c ç カ 🚴", result);
+
+ USetCodePoints range1(uset.getAlias());
+ auto range2(range1); // copy constructor
+ auto iter = range1.begin();
+ auto limit = range2.end();
+ // operator* with pre- and post-increment
+ assertEquals(WHERE, u'a', *iter);
+ ++iter;
+ assertEquals(WHERE, u'b', *iter);
+ assertEquals(WHERE, u'c', *++iter);
+ auto iter2(iter); // copy constructor
+ assertEquals(WHERE, u'c', *iter2++);
+ assertEquals(WHERE, u'ç', *iter2++);
+ assertEquals(WHERE, u'カ', *iter2);
+ assertTrue(WHERE, ++iter2 != limit);
+ auto iter3(iter2++);
+ assertEquals(WHERE, U'🚴', *iter3);
+ assertTrue(WHERE, iter2 == limit);
+}
+
+void USetHeaderOnlyTest::TestUSetRangeIterator() {
+ IcuTestErrorCode errorCode(*this, "TestUSetRangeIterator");
+ using U_HEADER_NESTED_NAMESPACE::USetRanges;
+ using U_HEADER_NESTED_NAMESPACE::CodePointRange;
+ LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴]", -1, errorCode));
+ std::u16string result;
+ for (auto [start, end] : USetRanges(uset.getAlias())) {
+ // Commented-out sample code for pasting into the API docs.
+ // printf("uset.range U+%04lx..U+%04lx\n", (long)start, (long)end);
+ result.append(u" ").append(cpString(start)).append(u"-").append(cpString(end));
+ }
+ assertEquals(WHERE, u" a-c ç-ç カ-カ 🚴-🚴", result);
+ result.clear();
+ for (auto range : USetRanges(uset.getAlias())) {
+ for (UChar32 c : range) {
+ // Commented-out sample code for pasting into the API docs.
+ // printf("uset.range.c U+%04lx\n", (long)c);
+ result.append(u" ").append(cpString(c));
+ }
+ result.append(u" |");
+ }
+ assertEquals(WHERE, u" a b c | ç | カ | 🚴 |", result);
+
+ USetRanges range1(uset.getAlias());
+ auto range2(range1); // copy constructor
+ auto iter = range1.begin();
+ auto limit = range2.end();
+ // operator* with pre- and post-increment
+ {
+ auto cpRange = *iter;
+ assertEquals(WHERE, u'a', cpRange.rangeStart);
+ assertEquals(WHERE, u'c', cpRange.rangeEnd);
+ assertEquals(WHERE, 3, cpRange.size());
+ auto cpRange2(cpRange);
+ auto cpIter = cpRange.begin();
+ auto cpLimit = cpRange2.end();
+ assertEquals(WHERE, u'a', *cpIter++);
+ assertEquals(WHERE, u'b', *cpIter);
+ assertTrue(WHERE, cpIter != cpLimit);
+ CodePointRange::iterator cpIter2(u'b'); // public constructor
+ assertTrue(WHERE, cpIter == cpIter2);
+ assertEquals(WHERE, u'c', *++cpIter);
+ assertTrue(WHERE, cpIter != cpIter2);
+ assertTrue(WHERE, ++cpIter == cpLimit);
+ }
+ ++iter;
+ auto iter2(iter); // copy constructor
+ assertEquals(WHERE, u'ç', (*iter2).rangeStart);
+ assertEquals(WHERE, u'ç', (*iter2).rangeEnd);
+ assertEquals(WHERE, 1, (*iter2).size());
+ assertEquals(WHERE, u'ç', (*iter2++).rangeStart);
+ assertEquals(WHERE, u'カ', (*iter2).rangeStart);
+ assertTrue(WHERE, ++iter2 != limit);
+ auto iter3(iter2++);
+ assertEquals(WHERE, U'🚴', (*iter3).rangeStart);
+ assertTrue(WHERE, iter2 == limit);
+
+ {
+ CodePointRange cpRange(u'h', u'k'); // public constructor
+ // FYI: currently no operator==
+ assertEquals(WHERE, u'h', cpRange.rangeStart);
+ assertEquals(WHERE, u'k', cpRange.rangeEnd);
+ assertEquals(WHERE, 4, cpRange.size());
+ assertEquals(WHERE, u'i', *++(cpRange.begin()));
+ }
+}
+
+void USetHeaderOnlyTest::TestUSetStringIterator() {
+ IcuTestErrorCode errorCode(*this, "TestUSetStringIterator");
+ using U_HEADER_NESTED_NAMESPACE::USetStrings;
+ LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴{}{abc}{de}]", -1, errorCode));
+ std::u16string result;
+ for (auto s : USetStrings(uset.getAlias())) {
+ // Commented-out sample code for pasting into the API docs.
+ // Needs U_SHOW_CPLUSPLUS_API=1 for UnicodeString.
+ // UnicodeString us(s);
+ // std::string u8;
+ // printf("uset.string length %ld \"%s\"\n", (long)s.length(), us.toUTF8String(u8).c_str());
+ result.append(u" \"").append(s).append(u"\"");
+ }
+ assertEquals(WHERE, uR"( "" "abc" "de")", result);
+
+ USetStrings range1(uset.getAlias());
+ auto range2(range1); // copy constructor
+ auto iter = range1.begin();
+ auto limit = range2.end();
+ // operator* with pre- and post-increment
+ assertEquals(WHERE, u"", *iter);
+ assertEquals(WHERE, u"abc", *++iter);
+ auto iter2(iter); // copy constructor
+ assertEquals(WHERE, u"abc", *iter2++);
+ assertTrue(WHERE, iter2 != limit);
+ auto iter3(iter2++);
+ assertEquals(WHERE, u"de", *iter3);
+ assertTrue(WHERE, iter2 == limit);
+}
+
+void USetHeaderOnlyTest::TestUSetElementIterator() {
+ IcuTestErrorCode errorCode(*this, "TestUSetElementIterator");
+ using U_HEADER_NESTED_NAMESPACE::USetElements;
+ LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴{}{abc}{de}]", -1, errorCode));
+ std::u16string result;
+ for (auto el : USetElements(uset.getAlias())) {
+ // Commented-out sample code for pasting into the API docs.
+ // Needs U_SHOW_CPLUSPLUS_API=1 for UnicodeString.
+ // UnicodeString us(el);
+ // std::string u8;
+ // printf("uset.string length %ld \"%s\"\n", (long)us.length(), us.toUTF8String(u8).c_str());
+ result.append(u" \"").append(el).append(u"\"");
+ }
+ assertEquals(WHERE, uR"( "a" "b" "c" "ç" "カ" "🚴" "" "abc" "de")", result);
+
+ USetElements range1(uset.getAlias());
+ auto range2(range1); // copy constructor
+ auto iter = range1.begin();
+ auto limit = range2.end();
+ // operator* with pre- and post-increment
+ assertEquals(WHERE, u"a", *iter);
+ ++iter;
+ assertEquals(WHERE, u"b", *iter);
+ assertEquals(WHERE, u"c", *++iter);
+ auto iter2(iter); // copy constructor
+ assertEquals(WHERE, u"c", *iter2++);
+ // skip çカ🚴
+ ++++++iter2;
+ assertEquals(WHERE, u"", *iter2++);
+ assertEquals(WHERE, u"abc", *iter2);
+ assertTrue(WHERE, ++iter2 != limit);
+ auto iter3(iter2++);
+ assertEquals(WHERE, u"de", *iter3);
+ assertTrue(WHERE, iter2 == limit);
+}
diff --git a/icu4c/source/test/intltest/usettest.cpp b/icu4c/source/test/intltest/usettest.cpp
index 477639e86598..9da0612b148b 100644
--- a/icu4c/source/test/intltest/usettest.cpp
+++ b/icu4c/source/test/intltest/usettest.cpp
@@ -107,13 +107,9 @@ UnicodeSetTest::runIndexedTest(int32_t index, UBool exec,
TESTCASE_AUTO(TestSkipToStrings);
TESTCASE_AUTO(TestPatternCodePointComplement);
TESTCASE_AUTO(TestCodePointIterator);
- TESTCASE_AUTO(TestUSetCodePointIterator);
TESTCASE_AUTO(TestRangeIterator);
- TESTCASE_AUTO(TestUSetRangeIterator);
TESTCASE_AUTO(TestStringIterator);
- TESTCASE_AUTO(TestUSetStringIterator);
TESTCASE_AUTO(TestElementIterator);
- TESTCASE_AUTO(TestUSetElementIterator);
TESTCASE_AUTO_END;
}
@@ -4280,37 +4276,8 @@ void UnicodeSetTest::TestCodePointIterator() {
}
assertEquals(WHERE, u" a b c ç カ 🚴", result);
- // codePoints() returns USetCodePoints for which explicit APIs are tested via USet.
-}
-
-void UnicodeSetTest::TestUSetCodePointIterator() {
- IcuTestErrorCode errorCode(*this, "TestUSetCodePointIterator");
- using U_HEADER_NESTED_NAMESPACE::USetCodePoints;
- LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴]", -1, errorCode));
- UnicodeString result;
- for (UChar32 c : USetCodePoints(uset.getAlias())) {
- // printf("uset.codePoint U+%04lx\n", (long)c);
- result.append(u' ').append(c);
- }
- assertEquals(WHERE, u" a b c ç カ 🚴", result);
-
- USetCodePoints range1(uset.getAlias());
- auto range2(range1); // copy constructor
- auto iter = range1.begin();
- auto limit = range2.end();
- // operator* with pre- and post-increment
- assertEquals(WHERE, u'a', *iter);
- ++iter;
- assertEquals(WHERE, u'b', *iter);
- assertEquals(WHERE, u'c', *++iter);
- auto iter2(iter); // copy constructor
- assertEquals(WHERE, u'c', *iter2++);
- assertEquals(WHERE, u'ç', *iter2++);
- assertEquals(WHERE, u'カ', *iter2);
- assertTrue(WHERE, ++iter2 != limit);
- auto iter3(iter2++);
- assertEquals(WHERE, U'🚴', *iter3);
- assertTrue(WHERE, iter2 == limit);
+ // codePoints() returns USetCodePoints for which explicit APIs are tested via USet
+ // in a header-only unit test file.
}
void UnicodeSetTest::TestRangeIterator() {
@@ -4332,72 +4299,8 @@ void UnicodeSetTest::TestRangeIterator() {
}
assertEquals(WHERE, u" a b c | ç | カ | 🚴 |", result);
- // ranges() returns USetRanges for which explicit APIs are tested via USet.
-}
-
-void UnicodeSetTest::TestUSetRangeIterator() {
- IcuTestErrorCode errorCode(*this, "TestUSetRangeIterator");
- using U_HEADER_NESTED_NAMESPACE::USetRanges;
- using U_HEADER_NESTED_NAMESPACE::CodePointRange;
- LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴]", -1, errorCode));
- UnicodeString result;
- for (auto [start, end] : USetRanges(uset.getAlias())) {
- // printf("uset.range U+%04lx..U+%04lx\n", (long)start, (long)end);
- result.append(u' ').append(start).append(u'-').append(end);
- }
- assertEquals(WHERE, u" a-c ç-ç カ-カ 🚴-🚴", result);
- result.remove();
- for (auto range : USetRanges(uset.getAlias())) {
- for (UChar32 c : range) {
- // printf("uset.range.c U+%04lx\n", (long)c);
- result.append(u' ').append(c);
- }
- result.append(u" |");
- }
- assertEquals(WHERE, u" a b c | ç | カ | 🚴 |", result);
-
- USetRanges range1(uset.getAlias());
- auto range2(range1); // copy constructor
- auto iter = range1.begin();
- auto limit = range2.end();
- // operator* with pre- and post-increment
- {
- auto cpRange = *iter;
- assertEquals(WHERE, u'a', cpRange.rangeStart);
- assertEquals(WHERE, u'c', cpRange.rangeEnd);
- assertEquals(WHERE, 3, cpRange.size());
- auto cpRange2(cpRange);
- auto cpIter = cpRange.begin();
- auto cpLimit = cpRange2.end();
- assertEquals(WHERE, u'a', *cpIter++);
- assertEquals(WHERE, u'b', *cpIter);
- assertTrue(WHERE, cpIter != cpLimit);
- CodePointRange::iterator cpIter2(u'b'); // public constructor
- assertTrue(WHERE, cpIter == cpIter2);
- assertEquals(WHERE, u'c', *++cpIter);
- assertTrue(WHERE, cpIter != cpIter2);
- assertTrue(WHERE, ++cpIter == cpLimit);
- }
- ++iter;
- auto iter2(iter); // copy constructor
- assertEquals(WHERE, u'ç', (*iter2).rangeStart);
- assertEquals(WHERE, u'ç', (*iter2).rangeEnd);
- assertEquals(WHERE, 1, (*iter2).size());
- assertEquals(WHERE, u'ç', (*iter2++).rangeStart);
- assertEquals(WHERE, u'カ', (*iter2).rangeStart);
- assertTrue(WHERE, ++iter2 != limit);
- auto iter3(iter2++);
- assertEquals(WHERE, U'🚴', (*iter3).rangeStart);
- assertTrue(WHERE, iter2 == limit);
-
- {
- CodePointRange cpRange(u'h', u'k'); // public constructor
- // FYI: currently no operator==
- assertEquals(WHERE, u'h', cpRange.rangeStart);
- assertEquals(WHERE, u'k', cpRange.rangeEnd);
- assertEquals(WHERE, 4, cpRange.size());
- assertEquals(WHERE, u'i', *++(cpRange.begin()));
- }
+ // ranges() returns USetRanges for which explicit APIs are tested via USet
+ // in a header-only unit test file.
}
void UnicodeSetTest::TestStringIterator() {
@@ -4412,35 +4315,8 @@ void UnicodeSetTest::TestStringIterator() {
}
assertEquals(WHERE, uR"( "" "abc" "de")", result);
- // strings() returns USetStrins for which explicit APIs are tested via USet.
-}
-
-void UnicodeSetTest::TestUSetStringIterator() {
- IcuTestErrorCode errorCode(*this, "TestUSetStringIterator");
- using U_HEADER_NESTED_NAMESPACE::USetStrings;
- LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴{}{abc}{de}]", -1, errorCode));
- UnicodeString result;
- for (auto s : USetStrings(uset.getAlias())) {
- // UnicodeString us(s);
- // std::string u8;
- // printf("uset.string length %ld \"%s\"\n", (long)s.length(), us.toUTF8String(u8).c_str());
- result.append(u" \"").append(s).append(u'"');
- }
- assertEquals(WHERE, uR"( "" "abc" "de")", result);
-
- USetStrings range1(uset.getAlias());
- auto range2(range1); // copy constructor
- auto iter = range1.begin();
- auto limit = range2.end();
- // operator* with pre- and post-increment
- assertEquals(WHERE, UnicodeString(), UnicodeString(*iter));
- assertEquals(WHERE, u"abc", UnicodeString(*++iter));
- auto iter2(iter); // copy constructor
- assertEquals(WHERE, u"abc", UnicodeString(*iter2++));
- assertTrue(WHERE, iter2 != limit);
- auto iter3(iter2++);
- assertEquals(WHERE, u"de", UnicodeString(*iter3));
- assertTrue(WHERE, iter2 == limit);
+ // strings() returns USetStrins for which explicit APIs are tested via USet
+ // in a header-only unit test file.
}
void UnicodeSetTest::TestElementIterator() {
@@ -4455,39 +4331,6 @@ void UnicodeSetTest::TestElementIterator() {
}
assertEquals(WHERE, uR"( "a" "b" "c" "ç" "カ" "🚴" "" "abc" "de")", result);
- // begin() & end() return USetElementIterator for which explicit APIs are tested via USet.
-}
-
-void UnicodeSetTest::TestUSetElementIterator() {
- IcuTestErrorCode errorCode(*this, "TestUSetElementIterator");
- using U_HEADER_NESTED_NAMESPACE::USetElements;
- LocalUSetPointer uset(uset_openPattern(u"[abcçカ🚴{}{abc}{de}]", -1, errorCode));
- UnicodeString result;
- for (auto el : USetElements(uset.getAlias())) {
- // UnicodeString us(el);
- // std::string u8;
- // printf("uset.string length %ld \"%s\"\n", (long)us.length(), us.toUTF8String(u8).c_str());
- result.append(u" \"").append(el).append(u'"');
- }
- assertEquals(WHERE, uR"( "a" "b" "c" "ç" "カ" "🚴" "" "abc" "de")", result);
-
- USetElements range1(uset.getAlias());
- auto range2(range1); // copy constructor
- auto iter = range1.begin();
- auto limit = range2.end();
- // operator* with pre- and post-increment
- assertEquals(WHERE, u"a", *iter);
- ++iter;
- assertEquals(WHERE, u"b", *iter);
- assertEquals(WHERE, u"c", *++iter);
- auto iter2(iter); // copy constructor
- assertEquals(WHERE, u"c", *iter2++);
- // skip çカ🚴
- ++++++iter2;
- assertEquals(WHERE, UnicodeString(), *iter2++);
- assertEquals(WHERE, u"abc", *iter2);
- assertTrue(WHERE, ++iter2 != limit);
- auto iter3(iter2++);
- assertEquals(WHERE, u"de", *iter3);
- assertTrue(WHERE, iter2 == limit);
+ // begin() & end() return USetElementIterator for which explicit APIs are tested via USet
+ // in a header-only unit test file.
}
diff --git a/icu4c/source/test/intltest/usettest.h b/icu4c/source/test/intltest/usettest.h
index 0127042c7365..2ac22ba72e62 100644
--- a/icu4c/source/test/intltest/usettest.h
+++ b/icu4c/source/test/intltest/usettest.h
@@ -106,13 +106,9 @@ class UnicodeSetTest: public IntlTest {
void TestPatternCodePointComplement();
void TestCodePointIterator();
- void TestUSetCodePointIterator();
void TestRangeIterator();
- void TestUSetRangeIterator();
void TestStringIterator();
- void TestUSetStringIterator();
void TestElementIterator();
- void TestUSetElementIterator();
private: