Make QStringLiteral and QByteArrayLiteral always return the real types
Up until now, the macros would return an internal type that contained the pointer to the data. This breaks code that tried to use the macros with operators, like QStringBuilder but also when writing: QStringList() << QStringLiteral("a") << QStringLiteral("b"); This change seems to work fine now and I can also verify that this works: const auto str = QStringLiteral("Hello"); Even though it creates a QString, which is non-POD and non-constexpr. Change-Id: Iaf82af9bea4245513a1128ea54f9d2d3d785fb09 Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
This commit is contained in:
parent
33371c016e
commit
d631c31235
@ -169,13 +169,14 @@ struct QByteArrayDataPtr
|
||||
#if defined(Q_COMPILER_LAMBDA)
|
||||
|
||||
# define QByteArrayLiteral(str) \
|
||||
([]() -> QByteArrayDataPtr { \
|
||||
([]() -> QByteArray { \
|
||||
enum { Size = sizeof(str) - 1 }; \
|
||||
static const QStaticByteArrayData<Size> qbytearray_literal = { \
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(Size), \
|
||||
str }; \
|
||||
QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; \
|
||||
return holder; \
|
||||
const QByteArray ba(holder); \
|
||||
return ba; \
|
||||
}()) \
|
||||
/**/
|
||||
|
||||
@ -185,22 +186,22 @@ struct QByteArrayDataPtr
|
||||
// To do that, we need the __extension__ {( )} trick which only GCC supports
|
||||
|
||||
# define QByteArrayLiteral(str) \
|
||||
__extension__ ({ \
|
||||
QByteArray(__extension__ ({ \
|
||||
enum { Size = sizeof(str) - 1 }; \
|
||||
static const QStaticByteArrayData<Size> qbytearray_literal = { \
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(Size), \
|
||||
str }; \
|
||||
QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; \
|
||||
holder; \
|
||||
}) \
|
||||
})) \
|
||||
/**/
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef QByteArrayLiteral
|
||||
// no lambdas, not GCC, use const char * instead
|
||||
// no lambdas, not GCC, just return a temporary QByteArray
|
||||
|
||||
# define QByteArrayLiteral(str) (str)
|
||||
# define QByteArrayLiteral(str) QByteArray(str, sizeof(str) - 1)
|
||||
#endif
|
||||
|
||||
class Q_CORE_EXPORT QByteArray
|
||||
|
@ -113,13 +113,14 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
|
||||
# if defined(Q_COMPILER_LAMBDA)
|
||||
|
||||
# define QStringLiteral(str) \
|
||||
([]() -> QStringDataPtr { \
|
||||
([]() -> QString { \
|
||||
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
|
||||
static const QStaticStringData<Size> qstring_literal = { \
|
||||
Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \
|
||||
QT_UNICODE_LITERAL(str) }; \
|
||||
QStringDataPtr holder = { qstring_literal.data_ptr() }; \
|
||||
return holder; \
|
||||
const QString s(holder); \
|
||||
return s; \
|
||||
}()) \
|
||||
/**/
|
||||
|
||||
@ -129,14 +130,14 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
|
||||
// To do that, we need the __extension__ {( )} trick which only GCC supports
|
||||
|
||||
# define QStringLiteral(str) \
|
||||
__extension__ ({ \
|
||||
QString(__extension__ ({ \
|
||||
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
|
||||
static const QStaticStringData<Size> qstring_literal = { \
|
||||
Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \
|
||||
QT_UNICODE_LITERAL(str) }; \
|
||||
QStringDataPtr holder = { qstring_literal.data_ptr() }; \
|
||||
holder; \
|
||||
}) \
|
||||
})) \
|
||||
/**/
|
||||
|
||||
# endif
|
||||
@ -144,9 +145,10 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
|
||||
|
||||
#ifndef QStringLiteral
|
||||
// no lambdas, not GCC, or GCC in C++98 mode with 4-byte wchar_t
|
||||
// fallback, uses QLatin1String as next best options
|
||||
// fallback, return a temporary QString
|
||||
// source code is assumed to be encoded in UTF-8
|
||||
|
||||
# define QStringLiteral(str) QLatin1String(str)
|
||||
# define QStringLiteral(str) QString::fromUtf8(str, sizeof(str) - 1)
|
||||
#endif
|
||||
|
||||
#define Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
|
||||
|
@ -253,19 +253,6 @@ template <> struct QConcatenable<QString> : private QAbstractConcatenable
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct QConcatenable<QStringDataPtr> : private QAbstractConcatenable
|
||||
{
|
||||
typedef QStringDataPtr type;
|
||||
typedef QString ConvertTo;
|
||||
enum { ExactSize = true };
|
||||
static int size(const type &a) { return a.ptr->size; }
|
||||
static inline void appendTo(const type &a, QChar *&out)
|
||||
{
|
||||
memcpy(out, reinterpret_cast<const char*>(a.ptr->data()), sizeof(QChar) * a.ptr->size);
|
||||
out += a.ptr->size;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
|
||||
{
|
||||
typedef QStringRef type;
|
||||
@ -358,24 +345,6 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct QConcatenable<QByteArrayDataPtr> : private QAbstractConcatenable
|
||||
{
|
||||
typedef QByteArrayDataPtr type;
|
||||
typedef QByteArray ConvertTo;
|
||||
enum { ExactSize = false };
|
||||
static int size(const type &ba) { return ba.ptr->size; }
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
static inline QT_ASCII_CAST_WARN void appendTo(const type &a, QChar *&out)
|
||||
{
|
||||
QAbstractConcatenable::convertFromAscii(a.ptr->data(), a.ptr->size, out);
|
||||
}
|
||||
#endif
|
||||
static inline void appendTo(const type &ba, char *&out)
|
||||
{
|
||||
::memcpy(out, ba.ptr->data(), ba.ptr->size);
|
||||
out += ba.ptr->size;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct QConcatenable< QStringBuilder<A, B> >
|
||||
|
@ -107,21 +107,6 @@ void runScenario()
|
||||
QCOMPARE(r, r3);
|
||||
#endif
|
||||
|
||||
{
|
||||
static const QStaticStringData<12> literalData = {
|
||||
Q_STATIC_STRING_DATA_HEADER_INITIALIZER(12),
|
||||
{ 's', 'o', 'm', 'e', ' ', 'l', 'i', 't', 'e', 'r', 'a', 'l' }
|
||||
};
|
||||
static QStringDataPtr literal = { literalData.data_ptr() };
|
||||
|
||||
r = literal;
|
||||
QCOMPARE(r, string);
|
||||
r = r Q literal;
|
||||
QCOMPARE(r, r2);
|
||||
r = literal Q literal;
|
||||
QCOMPARE(r, r2);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
r = string P LITERAL;
|
||||
QCOMPARE(r, r2);
|
||||
@ -226,21 +211,6 @@ void runScenario()
|
||||
QCOMPARE(r, ba);
|
||||
}
|
||||
|
||||
{
|
||||
static const QStaticByteArrayData<12> literalData = {
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(12),
|
||||
{ 's', 'o', 'm', 'e', ' ', 'l', 'i', 't', 'e', 'r', 'a', 'l' }
|
||||
};
|
||||
static QByteArrayDataPtr literal = { literalData.data_ptr() };
|
||||
|
||||
QByteArray ba = literal;
|
||||
QCOMPARE(ba, QByteArray(LITERAL));
|
||||
ba = ba Q literal;
|
||||
QCOMPARE(ba, QByteArray(LITERAL LITERAL));
|
||||
ba = literal Q literal;
|
||||
QCOMPARE(ba, QByteArray(LITERAL LITERAL));
|
||||
}
|
||||
|
||||
//operator QString +=
|
||||
{
|
||||
QString str = QString::fromUtf8(UTF8_LITERAL);
|
||||
|
Loading…
Reference in New Issue
Block a user