QString: de-inline toStdString() so we can avoid a QByteArray temporary
We can simply write the UTF-8 string into the std::string buffer, bypassing our temporary. And when Qt is compiled with C++23, we even get resize_and_overwrite() support, removing the unnecessary memset() - though the compiler might have been smart enough to suppress it (GCC and Clang currently aren't that smart; in fact, GCC even generates code to deal with a default-constructed std::string not being empty). Change-Id: I3883268b30a9065757dcfffd6da4705a4aa44d7a Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
parent
f846754663
commit
3b73bc463d
@ -9374,6 +9374,26 @@ QString::iterator QString::erase(QString::const_iterator first, QString::const_i
|
||||
|
||||
\sa toLatin1(), toUtf8(), toLocal8Bit(), QByteArray::toStdString()
|
||||
*/
|
||||
std::string QString::toStdString() const
|
||||
{
|
||||
std::string result;
|
||||
if (isEmpty())
|
||||
return result;
|
||||
|
||||
auto writeToBuffer = [this](char *out, size_t) {
|
||||
char *last = QUtf8::convertFromUnicode(out, *this);
|
||||
return last - out;
|
||||
};
|
||||
size_t maxSize = size() * 3; // worst case for UTF-8
|
||||
#ifdef __cpp_lib_string_resize_and_overwrite
|
||||
// C++23
|
||||
result.resize_and_overwrite(maxSize, writeToBuffer);
|
||||
#else
|
||||
result.resize(maxSize);
|
||||
result.resize(writeToBuffer(result.data(), result.size()));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString QString::fromRawData(const char16_t *unicode, qsizetype size)
|
||||
|
@ -1086,7 +1086,7 @@ public:
|
||||
}
|
||||
|
||||
static inline QString fromStdString(const std::string &s);
|
||||
inline std::string toStdString() const;
|
||||
std::string toStdString() const;
|
||||
static inline QString fromStdWString(const std::wstring &s);
|
||||
inline std::wstring toStdWString() const;
|
||||
|
||||
@ -1573,9 +1573,6 @@ QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const QByteArray &rhs
|
||||
# endif // QT_NO_CAST_FROM_ASCII
|
||||
#endif // QT_USE_QSTRINGBUILDER
|
||||
|
||||
std::string QString::toStdString() const
|
||||
{ return toUtf8().toStdString(); }
|
||||
|
||||
QString QString::fromStdString(const std::string &s)
|
||||
{ return fromUtf8(s.data(), qsizetype(s.size())); }
|
||||
|
||||
|
@ -691,6 +691,14 @@ char *QUtf8::convertFromUnicode(char *out, QStringView in, OnErrorLambda &&onErr
|
||||
return reinterpret_cast<char *>(dst);
|
||||
}
|
||||
|
||||
char *QUtf8::convertFromUnicode(char *dst, QStringView in) noexcept
|
||||
{
|
||||
return convertFromUnicode(dst, in, [](auto *dst, ...) {
|
||||
// encoding error - append '?'
|
||||
*dst++ = '?';
|
||||
});
|
||||
}
|
||||
|
||||
QByteArray QUtf8::convertFromUnicode(QStringView in)
|
||||
{
|
||||
qsizetype len = in.size();
|
||||
@ -698,11 +706,7 @@ QByteArray QUtf8::convertFromUnicode(QStringView in)
|
||||
// create a QByteArray with the worst case scenario size
|
||||
QByteArray result(len * 3, Qt::Uninitialized);
|
||||
char *dst = const_cast<char *>(result.constData());
|
||||
dst = convertFromUnicode(dst, in, [](auto *dst, ...) {
|
||||
// encoding error - append '?'
|
||||
*dst++ = '?';
|
||||
});
|
||||
|
||||
dst = convertFromUnicode(dst, in);
|
||||
result.truncate(dst - result.constData());
|
||||
return result;
|
||||
}
|
||||
|
@ -320,6 +320,7 @@ struct QUtf8
|
||||
|
||||
static char16_t *convertToUnicode(char16_t *dst, QByteArrayView in, QStringConverter::State *state);
|
||||
|
||||
static char *convertFromUnicode(char *dst, QStringView in) noexcept;
|
||||
Q_CORE_EXPORT static QByteArray convertFromUnicode(QStringView in);
|
||||
Q_CORE_EXPORT static QByteArray convertFromUnicode(QStringView in, QStringConverter::State *state);
|
||||
static char *convertFromUnicode(char *out, QStringView in, QStringConverter::State *state);
|
||||
|
Loading…
x
Reference in New Issue
Block a user