-
-
Notifications
You must be signed in to change notification settings - Fork 758
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ICU-22954 header-only-test USet C++ iterators
- Loading branch information
Showing
7 changed files
with
224 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
// © 2024 and later: Unicode, Inc. and others. | ||
// License & terms of use: http://www.unicode.org/copyright.html | ||
|
||
// headeronlytest.cpp | ||
// created: 2024dec11 Markus W. Scherer | ||
|
||
#include <string> | ||
#include <string_view> | ||
|
||
// Test header-only ICU C++ APIs. Do not use other ICU C++ APIs. | ||
#define U_SHOW_CPLUSPLUS_API 0 | ||
#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" | ||
|
||
using namespace std::string_view_literals; | ||
|
||
class HeaderOnlyTest : public IntlTest { | ||
public: | ||
HeaderOnlyTest() {} | ||
|
||
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=nullptr) override; | ||
|
||
void TestUSetCodePointIterator(); | ||
void TestUSetRangeIterator(); | ||
void TestUSetStringIterator(); | ||
void TestUSetElementIterator(); | ||
}; | ||
|
||
extern IntlTest *createHeaderOnlyTest() { | ||
return new HeaderOnlyTest(); | ||
} | ||
|
||
void HeaderOnlyTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { | ||
if(exec) { | ||
logln("TestSuite HeaderOnlyTest: "); | ||
} | ||
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<char16_t>(c)}; | ||
} else { | ||
return {U16_LEAD(c), U16_TRAIL(c)}; | ||
} | ||
} | ||
|
||
void HeaderOnlyTest::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())) { | ||
// 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 HeaderOnlyTest::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())) { | ||
// 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) { | ||
// 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 HeaderOnlyTest::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())) { | ||
// 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""sv, *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 HeaderOnlyTest::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())) { | ||
// 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""sv, *iter2++); | ||
assertEquals(WHERE, u"abc", *iter2); | ||
assertTrue(WHERE, ++iter2 != limit); | ||
auto iter3(iter2++); | ||
assertEquals(WHERE, u"de", *iter3); | ||
assertTrue(WHERE, iter2 == limit); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.