From 641e010cc7b52b6c3ac213e151781ffcbdd89145 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 30 Mar 2017 20:06:22 +0200 Subject: QStringBuilder: add support for char16_t{,*,[]} [ChangeLog][QtCore][QStringBuilder] Added support for char16_t characters and strings. Change-Id: Iee727f07226f2a326ae0df28d44930336cd8f71e Reviewed-by: Milian Wolff Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Edward Welbourne --- src/corelib/tools/qstringbuilder.cpp | 3 +- src/corelib/tools/qstringbuilder.h | 52 ++++++++++++++++++++++ .../qstringbuilder1/stringbuilder.cpp | 41 +++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp index 8300da30c2..37b0e08caf 100644 --- a/src/corelib/tools/qstringbuilder.cpp +++ b/src/corelib/tools/qstringbuilder.cpp @@ -74,8 +74,9 @@ QT_BEGIN_NAMESPACE \list \li QString, QStringRef, - \li QChar, QCharRef, QLatin1Char, + \li QChar, QCharRef, QLatin1Char, (since 5.10:) \c char16_t, \li QLatin1String, + \li (since 5.10:) \c{const char16_t[]} (\c{u"foo"}), \li QByteArray, \c char, \c{const char[]}. \endlist diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 5c6d990314..e9ca2245ba 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -187,6 +187,18 @@ template <> struct QConcatenable : private QAbstractConcatenable { *out++ = c; } }; +#if defined(Q_COMPILER_UNICODE_STRINGS) +template <> struct QConcatenable : private QAbstractConcatenable +{ + typedef char16_t type; + typedef QString ConvertTo; + enum { ExactSize = true }; + static Q_DECL_CONSTEXPR int size(char16_t) { return 1; } + static inline void appendTo(char16_t c, QChar *&out) + { *out++ = c; } +}; +#endif + template <> struct QConcatenable { typedef QLatin1Char type; @@ -325,6 +337,46 @@ template <> struct QConcatenable : QConcatenable typedef char *type; }; +#if defined(Q_COMPILER_UNICODE_STRINGS) +template struct QConcatenable : private QAbstractConcatenable +{ + using type = const char16_t[N]; + using ConvertTo = QString; + enum { ExactSize = true }; + static int size(const char16_t[N]) { return N - 1; } + static void appendTo(const char16_t a[N], QChar *&out) + { + memcpy(out, a, (N - 1) * sizeof(char16_t)); + out += N - 1; + } +}; + +template struct QConcatenable : QConcatenable +{ + using type = char16_t[N]; +}; + +template <> struct QConcatenable : private QAbstractConcatenable +{ + using type = const char16_t *; + using ConvertTo = QString; + enum { ExactSize = true }; + static int size(const char16_t *a) { return QStringView(a).length(); }; + static inline void QT_ASCII_CAST_WARN appendTo(const char16_t *a, QChar *&out) + { + if (!a) + return; + while (*a) + *out++ = *a++; + } +}; + +template <> struct QConcatenable : QConcatenable +{ + typedef char16_t *type; +}; +#endif // UNICODE_STRINGS + template <> struct QConcatenable : private QAbstractConcatenable { typedef QByteArray type; diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 32fb321931..4f7b05530c 100644 --- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp @@ -64,6 +64,11 @@ template <> QString toQString(const QLatin1String &l) { return l; } template <> QString toQString(const QLatin1Char &l) { return QChar(l); } template <> QString toQString(const QChar &c) { return c; } template <> QString toQString(const QChar::SpecialCharacter &c) { return QChar(c); } +#ifdef Q_COMPILER_UNICODE_STRINGS +template <> QString toQString(char16_t * const &p) { return QStringView(p).toString(); } +template QString toQString(const char16_t (&a)[N]) { return QStringView(a).toString(); } +template <> QString toQString(const char16_t &c) { return QChar(c); } +#endif template QByteArray toQByteArray(const T &t); @@ -82,6 +87,12 @@ void runScenario() QLatin1Char lchar('c'); QChar qchar(lchar); QChar::SpecialCharacter special(QChar::Nbsp); +#ifdef Q_COMPILER_UNICODE_STRINGS + char16_t u16char = UNICODE_LITERAL[0]; + char16_t u16chararray[] = { u's', 0xF6, u'm', 0xEB, u' ', u'l', 0xEF, u't', 0xEB, u'r', 0xE4, u'l', 0x00 }; + QCOMPARE(QStringView(u16chararray), QStringView(UNICODE_LITERAL)); + char16_t *u16charstar = u16chararray; +#endif #define CHECK(QorP, a1, a2) \ do { \ @@ -101,6 +112,9 @@ void runScenario() CHECK(P, l1string, qchar); CHECK(P, l1string, special); CHECK(P, l1string, QStringLiteral(LITERAL)); + CHECK(Q, l1string, u16char); + CHECK(Q, l1string, u16chararray); + CHECK(Q, l1string, u16charstar); CHECK(P, string, string); CHECK(P, string, stringref); @@ -108,26 +122,53 @@ void runScenario() CHECK(P, string, qchar); CHECK(P, string, special); CHECK(P, string, QStringLiteral(LITERAL)); + CHECK(Q, string, u16char); + CHECK(Q, string, u16chararray); + CHECK(Q, string, u16charstar); CHECK(P, stringref, stringref); CHECK(P, stringref, lchar); CHECK(P, stringref, qchar); CHECK(P, stringref, special); CHECK(P, stringref, QStringLiteral(LITERAL)); + CHECK(Q, stringref, u16char); + CHECK(Q, stringref, u16chararray); + CHECK(Q, stringref, u16charstar); CHECK(P, lchar, lchar); CHECK(P, lchar, qchar); CHECK(P, lchar, special); CHECK(P, lchar, QStringLiteral(LITERAL)); + CHECK(Q, lchar, u16char); + CHECK(Q, lchar, u16chararray); + CHECK(Q, lchar, u16charstar); CHECK(P, qchar, qchar); CHECK(P, qchar, special); CHECK(P, qchar, QStringLiteral(LITERAL)); + CHECK(Q, qchar, u16char); + CHECK(Q, qchar, u16chararray); + CHECK(Q, qchar, u16charstar); CHECK(P, special, special); CHECK(P, special, QStringLiteral(LITERAL)); + CHECK(Q, special, u16char); + CHECK(Q, special, u16chararray); + CHECK(Q, special, u16charstar); CHECK(P, QStringLiteral(LITERAL), QStringLiteral(LITERAL)); + CHECK(Q, QStringLiteral(LITERAL), u16char); + CHECK(Q, QStringLiteral(LITERAL), u16chararray); + CHECK(Q, QStringLiteral(LITERAL), u16charstar); + + // CHECK(Q, u16char, u16char); // BUILTIN <-> BUILTIN cat't be overloaded + // CHECK(Q, u16char, u16chararray); + // CHECK(Q, u16char, u16charstar); + + // CHECK(Q, u16chararray, u16chararray); // BUILTIN <-> BUILTIN cat't be overloaded + // CHECK(Q, u16chararray, u16charstar); + + // CHECK(Q, u16charstar, u16charstar); // BUILTIN <-> BUILTIN cat't be overloaded #undef DO -- cgit v1.2.3