mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-16 10:17:23 +00:00
ICU-22954 Make UCollator predicates usable without U_SHOW_CPLUSPLUS_API.
Until now, the implementation of the UCollator predicates has been using UnicodeString and StringPiece as convenient wrappers for converting from standard C++ data types to ICU4C data types. But as that doesn't work when the client uses ICU4C built without U_SHOW_CPLUSPLUS_API this is now changed to instead perform these conversions directly. (It's a bit more code, but does just the same thing in the end.)
This commit is contained in:
parent
e8c179dedd
commit
ee8806e87c
7 changed files with 164 additions and 9 deletions
|
@ -283,6 +283,32 @@ inline const char16_t *uprv_char16PtrFromUChar(const T *p) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
#if !U_CHAR16_IS_TYPEDEF && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 180000)
|
||||
/** @internal */
|
||||
inline const char16_t *uprv_char16PtrFromUint16(const uint16_t *p) {
|
||||
#if U_SHOW_CPLUSPLUS_API
|
||||
return ConstChar16Ptr(p).get();
|
||||
#else
|
||||
#ifdef U_ALIASING_BARRIER
|
||||
U_ALIASING_BARRIER(p);
|
||||
#endif
|
||||
return reinterpret_cast<const char16_t *>(p);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if U_SIZEOF_WCHAR_T==2
|
||||
/** @internal */
|
||||
inline const char16_t *uprv_char16PtrFromWchar(const wchar_t *p) {
|
||||
#if U_SHOW_CPLUSPLUS_API
|
||||
return ConstChar16Ptr(p).get();
|
||||
#else
|
||||
#ifdef U_ALIASING_BARRIER
|
||||
U_ALIASING_BARRIER(p);
|
||||
#endif
|
||||
return reinterpret_cast<const char16_t *>(p);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -1526,7 +1526,6 @@ ucol_openBinary(const uint8_t *bin, int32_t length,
|
|||
#include <type_traits>
|
||||
|
||||
#include "unicode/char16ptr.h"
|
||||
#include "unicode/stringpiece.h"
|
||||
#include "unicode/unistr.h"
|
||||
|
||||
namespace U_HEADER_ONLY_NAMESPACE {
|
||||
|
@ -1547,6 +1546,7 @@ class Predicate {
|
|||
/** @internal */
|
||||
explicit Predicate(const UCollator* ucol) : collator(ucol) {}
|
||||
|
||||
#if U_SHOW_CPLUSPLUS_API
|
||||
/** @internal */
|
||||
template <
|
||||
typename T, typename U,
|
||||
|
@ -1554,6 +1554,28 @@ class Predicate {
|
|||
bool operator()(const T& lhs, const U& rhs) const {
|
||||
return match(UnicodeString::readOnlyAlias(lhs), UnicodeString::readOnlyAlias(rhs));
|
||||
}
|
||||
#else
|
||||
/** @internal */
|
||||
bool operator()(std::u16string_view lhs, std::u16string_view rhs) const {
|
||||
return match(lhs, rhs);
|
||||
}
|
||||
|
||||
#if !U_CHAR16_IS_TYPEDEF && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 180000)
|
||||
/** @internal */
|
||||
bool operator()(std::basic_string_view<uint16_t> lhs, std::basic_string_view<uint16_t> rhs) const {
|
||||
return match({uprv_char16PtrFromUint16(lhs.data()), lhs.length()},
|
||||
{uprv_char16PtrFromUint16(rhs.data()), rhs.length()});
|
||||
}
|
||||
#endif
|
||||
|
||||
#if U_SIZEOF_WCHAR_T==2
|
||||
/** @internal */
|
||||
bool operator()(std::wstring_view lhs, std::wstring_view rhs) const {
|
||||
return match({uprv_char16PtrFromWchar(lhs.data()), lhs.length()},
|
||||
{uprv_char16PtrFromWchar(rhs.data()), rhs.length()});
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** @internal */
|
||||
bool operator()(std::string_view lhs, std::string_view rhs) const {
|
||||
|
@ -1563,27 +1585,28 @@ class Predicate {
|
|||
#if defined(__cpp_char8_t)
|
||||
/** @internal */
|
||||
bool operator()(std::u8string_view lhs, std::u8string_view rhs) const {
|
||||
return match(lhs, rhs);
|
||||
return match({reinterpret_cast<const char*>(lhs.data()), lhs.length()},
|
||||
{reinterpret_cast<const char*>(rhs.data()), rhs.length()});
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool match(UnicodeString lhs, UnicodeString rhs) const {
|
||||
bool match(std::u16string_view lhs, std::u16string_view rhs) const {
|
||||
return compare(
|
||||
ucol_strcoll(
|
||||
collator,
|
||||
toUCharPtr(lhs.getBuffer()), lhs.length(),
|
||||
toUCharPtr(rhs.getBuffer()), rhs.length()),
|
||||
toUCharPtr(lhs.data()), static_cast<int32_t>(lhs.length()),
|
||||
toUCharPtr(rhs.data()), static_cast<int32_t>(rhs.length())),
|
||||
result);
|
||||
}
|
||||
|
||||
bool match(StringPiece lhs, StringPiece rhs) const {
|
||||
bool match(std::string_view lhs, std::string_view rhs) const {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
return compare(
|
||||
ucol_strcollUTF8(
|
||||
collator,
|
||||
lhs.data(), lhs.length(),
|
||||
rhs.data(), rhs.length(),
|
||||
lhs.data(), static_cast<int32_t>(lhs.length()),
|
||||
rhs.data(), static_cast<int32_t>(rhs.length()),
|
||||
&status),
|
||||
result);
|
||||
}
|
||||
|
|
|
@ -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 usetheaderonlytest.o
|
||||
numbertest_simple.o uchar_type_build_test.o ucolheaderonlytest.o usetheaderonlytest.o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
|
|
|
@ -242,6 +242,7 @@
|
|||
<ClCompile Include="units_router_test.cpp" />
|
||||
<ClCompile Include="units_test.cpp" />
|
||||
<ClCompile Include="uchar_type_build_test.cpp" />
|
||||
<ClCompile Include="ucolheaderonlytest.cpp" />
|
||||
<ClCompile Include="usetheaderonlytest.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -580,6 +580,9 @@
|
|||
<ClCompile Include="messageformat2test_read_json.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ucolheaderonlytest.cpp">
|
||||
<Filter>misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="usetheaderonlytest.cpp">
|
||||
<Filter>misc</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#include "usettest.h"
|
||||
|
||||
extern IntlTest *createBytesTrieTest();
|
||||
#if !UCONFIG_NO_COLLATION
|
||||
extern IntlTest *createUColHeaderOnlyTest();
|
||||
#endif
|
||||
extern IntlTest *createUSetHeaderOnlyTest();
|
||||
extern IntlTest *createLocaleMatcherTest();
|
||||
static IntlTest *createLocalPointerTest();
|
||||
|
@ -83,6 +86,9 @@ void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &
|
|||
TESTCASE_AUTO_CLASS(LocaleBuilderTest);
|
||||
TESTCASE_AUTO_CREATE_CLASS(LocaleMatcherTest);
|
||||
TESTCASE_AUTO_CREATE_CLASS(UHashTest);
|
||||
#if !UCONFIG_NO_COLLATION
|
||||
TESTCASE_AUTO_CREATE_CLASS(UColHeaderOnlyTest);
|
||||
#endif
|
||||
TESTCASE_AUTO_CREATE_CLASS(USetHeaderOnlyTest);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
|
96
icu4c/source/test/intltest/ucolheaderonlytest.cpp
Normal file
96
icu4c/source/test/intltest/ucolheaderonlytest.cpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
// © 2025 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
// Test header-only ICU C++ APIs. Do not use other ICU C++ APIs.
|
||||
// Non-default configuration:
|
||||
#define U_SHOW_CPLUSPLUS_API 0
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_COLLATION
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "unicode/ucol.h"
|
||||
|
||||
#include "intltest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class UColHeaderOnlyTest : public IntlTest {
|
||||
public:
|
||||
UColHeaderOnlyTest() = default;
|
||||
void runIndexedTest(int32_t index, UBool exec, const char*& name, char* par = nullptr) override;
|
||||
void TestPredicateTypes();
|
||||
};
|
||||
|
||||
void UColHeaderOnlyTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char* /*par*/) {
|
||||
if (exec) {
|
||||
logln("TestSuite UColHeaderOnlyTest: ");
|
||||
}
|
||||
TESTCASE_AUTO_BEGIN;
|
||||
TESTCASE_AUTO(TestPredicateTypes);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
class UCollatorWrapper {
|
||||
public:
|
||||
UCollatorWrapper(const char* loc, UErrorCode* status) : ucol(ucol_open(loc, status)) {}
|
||||
~UCollatorWrapper() { ucol_close(ucol); }
|
||||
operator UCollator*() { return ucol; }
|
||||
|
||||
private:
|
||||
UCollator* ucol;
|
||||
};
|
||||
|
||||
constexpr char16_t TEXT_CHAR16[] = u"char16";
|
||||
#if !U_CHAR16_IS_TYPEDEF && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 180000)
|
||||
constexpr uint16_t TEXT_UINT16[] = {0x75, 0x69, 0x6e, 0x74, 0x31, 0x36, 0x00};
|
||||
#endif
|
||||
#if U_SIZEOF_WCHAR_T == 2
|
||||
constexpr wchar_t TEXT_WCHAR[] = L"wchar";
|
||||
#endif
|
||||
|
||||
constexpr char TEXT_CHAR[] = "char";
|
||||
#if defined(__cpp_char8_t)
|
||||
constexpr char8_t TEXT_CHAR8[] = u8"char8";
|
||||
#endif
|
||||
|
||||
// Verify that the UCollator predicates handle all string types.
|
||||
void UColHeaderOnlyTest::TestPredicateTypes() {
|
||||
using namespace U_HEADER_NESTED_NAMESPACE;
|
||||
IcuTestErrorCode status(*this, "TestPredicateTypes");
|
||||
UCollatorWrapper ucol("", status);
|
||||
status.assertSuccess();
|
||||
const auto equal_to = collator::equal_to(ucol);
|
||||
|
||||
assertTrue("char16_t", equal_to(TEXT_CHAR16, TEXT_CHAR16));
|
||||
assertTrue("u16string_view", equal_to(std::u16string_view{TEXT_CHAR16}, TEXT_CHAR16));
|
||||
|
||||
#if !U_CHAR16_IS_TYPEDEF && (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION < 180000)
|
||||
assertTrue("uint16_t", equal_to(TEXT_UINT16, TEXT_UINT16));
|
||||
assertTrue("basic_string_view<uint16_t>",
|
||||
equal_to(std::basic_string_view<uint16_t>{TEXT_UINT16}, TEXT_UINT16));
|
||||
#endif
|
||||
|
||||
#if U_SIZEOF_WCHAR_T == 2
|
||||
assertTrue("wchar_t", equal_to(TEXT_WCHAR, TEXT_WCHAR));
|
||||
assertTrue("wstring_view", equal_to(std::wstring_view{TEXT_WCHAR}, TEXT_WCHAR));
|
||||
#endif
|
||||
|
||||
assertTrue("char", equal_to(TEXT_CHAR, TEXT_CHAR));
|
||||
assertTrue("string_view", equal_to(std::string_view{TEXT_CHAR}, TEXT_CHAR));
|
||||
|
||||
#if defined(__cpp_char8_t)
|
||||
assertTrue("char8_t", equal_to(TEXT_CHAR8, TEXT_CHAR8));
|
||||
assertTrue("u8string_view", equal_to(std::u8string_view{TEXT_CHAR8}, TEXT_CHAR8));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
IntlTest* createUColHeaderOnlyTest() {
|
||||
return new UColHeaderOnlyTest();
|
||||
}
|
||||
|
||||
#endif // !UCONFIG_NO_COLLATION
|
Loading…
Add table
Reference in a new issue