Move QStringRef and remains into Qt5Compat

Task-number: QTBUG-84437
Change-Id: Ia18737f63995164edf2857321070913969518cf1
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
This commit is contained in:
Karsten Heimrich 2020-08-03 11:19:16 +02:00
parent b690a43e43
commit 80ffb97660
33 changed files with 5934 additions and 4 deletions

View File

@ -1,4 +1,4 @@
dependencies:
../qtbase:
ref: eb7d1cf098df56f8ebf62f02af611a627435a4a1
ref: 4b1ffab8ad95eda737fde015c243442a28de8e23
required: true

View File

@ -15,6 +15,10 @@ qt_add_module(Core5Compat
serialization/qbinaryjsonarray.cpp serialization/qbinaryjsonarray_p.h
serialization/qbinaryjsonobject.cpp serialization/qbinaryjsonobject_p.h
serialization/qbinaryjsonvalue.cpp serialization/qbinaryjsonvalue_p.h
text/qstringref.cpp text/qstringref.h
DEFINES
QT_USE_FAST_OPERATOR_PLUS
QT_USE_QSTRINGBUILDER
LIBRARIES
Qt::CorePrivate
PUBLIC_LIBRARIES

View File

@ -9,6 +9,7 @@ QMAKE_DOCS = $$PWD/doc/qtcore5.qdocconf
include(codecs/codecs.pri)
include(serialization/serialization.pri)
include(text/text.pri)
PUBLIC_HEADERS += \
qcore5global.h \

File diff suppressed because it is too large Load Diff

487
src/core5/text/qstringref.h Normal file
View File

@ -0,0 +1,487 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2019 Intel Corporation.
** Copyright (C) 2019 Mail.ru Group.
** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSTRINGREF_H
#define QSTRINGREF_H
#if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
#error QT_NO_CAST_FROM_ASCII and QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
#endif
#include <QtCore/qchar.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qarraydata.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qhashfunctions.h>
#include <QtCore/qstringliteral.h>
#include <QtCore/qstringalgorithms.h>
#include <QtCore/qstringview.h>
#include <QtCore/qstringtokenizer.h>
#include <QtCore5Compat/qcore5global.h>
#include <iterator>
#ifdef truncate
#error qstringref.h must be included before any header file that defines truncate
#endif
QT_BEGIN_NAMESPACE
class Q_CORE5COMPAT_EXPORT QStringRef
{
const QString *m_string;
int m_position;
int m_size;
public:
typedef QString::size_type size_type;
typedef QString::value_type value_type;
typedef const QChar *const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef QString::const_pointer const_pointer;
typedef QString::const_reference const_reference;
constexpr QStringRef() noexcept
: m_string(nullptr), m_position(0), m_size(0) { }
inline QStringRef(const QString *string, int position, int size);
inline QStringRef(const QString *string);
inline const QString *string() const { return m_string; }
inline int position() const { return m_position; }
inline int size() const { return m_size; }
inline int count() const { return m_size; }
inline int length() const { return m_size; }
#if QT_STRINGVIEW_LEVEL < 2
int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(const QStringRef &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
int lastIndexOf(QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
#if QT_STRINGVIEW_LEVEL < 2
inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
inline bool contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
Q_REQUIRED_RESULT
QList<QStringRef> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
Q_REQUIRED_RESULT
QList<QStringRef> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
Q_REQUIRED_RESULT QStringRef left(int n) const;
Q_REQUIRED_RESULT QStringRef right(int n) const;
Q_REQUIRED_RESULT QStringRef mid(int pos, int n = -1) const;
Q_REQUIRED_RESULT QStringRef chopped(int n) const
{ Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return left(size() - n); }
void truncate(int pos) noexcept { m_size = qBound(0, pos, m_size); }
void chop(int n) noexcept
{
if (n >= m_size)
m_size = 0;
else if (n > 0)
m_size -= n;
}
bool isRightToLeft() const;
Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::startsWith(*this, s, cs); }
bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool startsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
Q_REQUIRED_RESULT bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::endsWith(*this, s, cs); }
bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#if QT_STRINGVIEW_LEVEL < 2
bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
#endif
inline operator QStringView() const {
if (!m_string)
return {};
return QStringView(m_string->data() + m_position, m_size);
}
inline QStringRef &operator=(const QString *string);
inline const QChar *unicode() const
{
static const char16_t _empty = 0;
if (!m_string)
return reinterpret_cast<const QChar *>(&_empty);
return m_string->unicode() + m_position;
}
inline const QChar *data() const { return unicode(); }
inline const QChar *constData() const { return unicode(); }
inline const_iterator begin() const { return unicode(); }
inline const_iterator cbegin() const { return unicode(); }
inline const_iterator constBegin() const { return unicode(); }
inline const_iterator end() const { return unicode() + size(); }
inline const_iterator cend() const { return unicode() + size(); }
inline const_iterator constEnd() const { return unicode() + size(); }
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
inline const_reverse_iterator crbegin() const { return rbegin(); }
inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
inline const_reverse_iterator crend() const { return rend(); }
Q_REQUIRED_RESULT QByteArray toLatin1() const;
Q_REQUIRED_RESULT QByteArray toUtf8() const;
Q_REQUIRED_RESULT QByteArray toLocal8Bit() const;
Q_REQUIRED_RESULT QList<uint> toUcs4() const;
inline void clear() { m_string = nullptr; m_position = m_size = 0; }
QString toString() const;
inline bool isEmpty() const { return m_size == 0; }
inline bool isNull() const { return m_string == nullptr || m_string->isNull(); }
QStringRef appendTo(QString *string) const;
inline const QChar at(int i) const
{ Q_ASSERT(uint(i) < uint(size())); return m_string->at(i + m_position); }
QChar operator[](int i) const { return at(i); }
Q_REQUIRED_RESULT QChar front() const { return at(0); }
Q_REQUIRED_RESULT QChar back() const { return at(size() - 1); }
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
// ASCII compatibility
inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
inline QT_ASCII_CAST_WARN bool operator<=(const char *s) const;
inline QT_ASCII_CAST_WARN bool operator>(const char *s) const;
inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const;
#endif
int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
int compare(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::compareStrings(*this, QStringView(&c, 1), cs); }
int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
int compare(const QByteArray &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return QStringRef::compare_helper(unicode(), size(), s.data(), qstrnlen(s.data(), s.size()), cs); }
#endif
static int compare(const QStringRef &s1, const QString &s2,
Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
static int compare(const QStringRef &s1, const QStringRef &s2,
Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
static int compare(const QStringRef &s1, QLatin1String s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
int localeAwareCompare(const QString &s) const;
int localeAwareCompare(const QStringRef &s) const;
static int localeAwareCompare(const QStringRef &s1, const QString &s2);
static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2);
Q_REQUIRED_RESULT QStringRef trimmed() const;
short toShort(bool *ok = nullptr, int base = 10) const;
ushort toUShort(bool *ok = nullptr, int base = 10) const;
int toInt(bool *ok = nullptr, int base = 10) const;
uint toUInt(bool *ok = nullptr, int base = 10) const;
long toLong(bool *ok = nullptr, int base = 10) const;
ulong toULong(bool *ok = nullptr, int base = 10) const;
qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
float toFloat(bool *ok = nullptr) const;
double toDouble(bool *ok = nullptr) const;
friend inline bool operator==(QChar, const QStringRef &) noexcept;
friend inline bool operator<(QChar, const QStringRef &) noexcept;
friend inline bool operator>(QChar, const QStringRef &) noexcept;
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
friend inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QStringRef &s2);
friend inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2);
friend inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QStringRef &s2);
friend inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QStringRef &s2);
friend inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QStringRef &s2);
friend inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2);
#endif
private:
static int compare_helper(const QChar *data1, qsizetype length1,
const QChar *data2, qsizetype length2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
static int compare_helper(const QChar *data1, qsizetype length1,
const char *data2, qsizetype length2,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
static int compare_helper(const QChar *data1, qsizetype length1,
QLatin1String s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
};
Q_DECLARE_TYPEINFO(QStringRef, Q_PRIMITIVE_TYPE);
namespace QtPrivate {
namespace Tok {
template <> struct ViewForImpl<QStringRef> : ViewForImpl<QStringView> {};
} // namespace Tok
} // namespace QtPrivate
#if QT_STRINGVIEW_LEVEL < 2
inline Q_DECL_PURE_FUNCTION size_t qHash(const QStringRef &key, size_t seed = 0) noexcept
{
return qHash(QStringView { key }, seed);
}
#endif
QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QStringRef)
inline QStringRef &QStringRef::operator=(const QString *aString)
{ m_string = aString; m_position = 0; m_size = aString?aString->size():0; return *this; }
inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize)
:m_string(aString), m_position(aPosition), m_size(aSize){}
inline QStringRef::QStringRef(const QString *aString)
:m_string(aString), m_position(0), m_size(aString?aString->size() : 0){}
// QStringRef <> QStringRef
Q_CORE5COMPAT_EXPORT bool operator==(const QStringRef &s1, const QStringRef &s2) noexcept;
inline bool operator!=(const QStringRef &s1, const QStringRef &s2) noexcept
{ return !(s1 == s2); }
Q_CORE5COMPAT_EXPORT bool operator<(const QStringRef &s1, const QStringRef &s2) noexcept;
inline bool operator>(const QStringRef &s1, const QStringRef &s2) noexcept
{ return s2 < s1; }
inline bool operator<=(const QStringRef &s1, const QStringRef &s2) noexcept
{ return !(s1 > s2); }
inline bool operator>=(const QStringRef &s1, const QStringRef &s2) noexcept
{ return !(s1 < s2); }
// QString <> QStringRef
Q_CORE5COMPAT_EXPORT bool operator==(const QString &lhs, const QStringRef &rhs) noexcept;
inline bool operator!=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) != 0; }
inline bool operator< (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) < 0; }
inline bool operator> (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) > 0; }
inline bool operator<=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) <= 0; }
inline bool operator>=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) >= 0; }
inline bool operator==(const QStringRef &lhs, const QString &rhs) noexcept { return rhs == lhs; }
inline bool operator!=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs != lhs; }
inline bool operator< (const QStringRef &lhs, const QString &rhs) noexcept { return rhs > lhs; }
inline bool operator> (const QStringRef &lhs, const QString &rhs) noexcept { return rhs < lhs; }
inline bool operator<=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs >= lhs; }
inline bool operator>=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs <= lhs; }
inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const noexcept
{ return QStringRef::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const noexcept
{ return QStringRef::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
{ return QStringRef::compare_helper(constData(), length(), s, cs); }
inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) noexcept
{ return QStringRef::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) noexcept
{ return QStringRef::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) noexcept
{ return QStringRef::compare_helper(s1.constData(), s1.length(), s2, cs); }
// QLatin1String <> QStringRef
Q_CORE5COMPAT_EXPORT bool operator==(QLatin1String lhs, const QStringRef &rhs) noexcept;
inline bool operator!=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) != 0; }
inline bool operator< (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) > 0; }
inline bool operator> (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) < 0; }
inline bool operator<=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) >= 0; }
inline bool operator>=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) <= 0; }
inline bool operator==(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs == lhs; }
inline bool operator!=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs != lhs; }
inline bool operator< (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs > lhs; }
inline bool operator> (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs < lhs; }
inline bool operator<=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs >= lhs; }
inline bool operator>=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs <= lhs; }
// QChar <> QStringRef
inline bool operator==(QChar lhs, const QStringRef &rhs) noexcept
{ return rhs.size() == 1 && lhs == rhs.front(); }
inline bool operator< (QChar lhs, const QStringRef &rhs) noexcept
{ return QStringRef::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
inline bool operator> (QChar lhs, const QStringRef &rhs) noexcept
{ return QStringRef::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
inline bool operator!=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs == rhs); }
inline bool operator<=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs > rhs); }
inline bool operator>=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs < rhs); }
inline bool operator==(const QStringRef &lhs, QChar rhs) noexcept { return rhs == lhs; }
inline bool operator!=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
inline bool operator< (const QStringRef &lhs, QChar rhs) noexcept { return rhs > lhs; }
inline bool operator> (const QStringRef &lhs, QChar rhs) noexcept { return rhs < lhs; }
inline bool operator<=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
inline bool operator>=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
// QStringRef <> QByteArray
inline QT_ASCII_CAST_WARN bool operator==(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) == 0; }
inline QT_ASCII_CAST_WARN bool operator!=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) != 0; }
inline QT_ASCII_CAST_WARN bool operator< (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) < 0; }
inline QT_ASCII_CAST_WARN bool operator> (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) > 0; }
inline QT_ASCII_CAST_WARN bool operator<=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) <= 0; }
inline QT_ASCII_CAST_WARN bool operator>=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) >= 0; }
inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) == 0; }
inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) != 0; }
inline QT_ASCII_CAST_WARN bool operator< (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) > 0; }
inline QT_ASCII_CAST_WARN bool operator> (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) < 0; }
inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) >= 0; }
inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) <= 0; }
// QStringRef <> const char *
inline QT_ASCII_CAST_WARN bool QStringRef::operator==(const char *s) const
{ return QStringRef::compare_helper(constData(), size(), s, -1) == 0; }
inline QT_ASCII_CAST_WARN bool QStringRef::operator!=(const char *s) const
{ return QStringRef::compare_helper(constData(), size(), s, -1) != 0; }
inline QT_ASCII_CAST_WARN bool QStringRef::operator<(const char *s) const
{ return QStringRef::compare_helper(constData(), size(), s, -1) < 0; }
inline QT_ASCII_CAST_WARN bool QStringRef::operator<=(const char *s) const
{ return QStringRef::compare_helper(constData(), size(), s, -1) <= 0; }
inline QT_ASCII_CAST_WARN bool QStringRef::operator>(const char *s) const
{ return QStringRef::compare_helper(constData(), size(), s, -1) > 0; }
inline QT_ASCII_CAST_WARN bool QStringRef::operator>=(const char *s) const
{ return QStringRef::compare_helper(constData(), size(), s, -1) >= 0; }
inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QStringRef &s2)
{ return QStringRef::compare_helper(s2.constData(), s2.size(), s1, -1) == 0; }
inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2)
{ return QStringRef::compare_helper(s2.constData(), s2.size(), s1, -1) != 0; }
inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QStringRef &s2)
{ return QStringRef::compare_helper(s2.constData(), s2.size(), s1, -1) > 0; }
inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QStringRef &s2)
{ return QStringRef::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QStringRef &s2)
{ return QStringRef::compare_helper(s2.constData(), s2.size(), s1, -1) < 0; }
inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2)
{ return QStringRef::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
inline int QStringRef::localeAwareCompare(const QString &s) const
{ return QString::localeAwareCompare(QStringView{ *this }, QStringView{ s }); }
inline int QStringRef::localeAwareCompare(const QStringRef &s) const
{ return QString::localeAwareCompare(QStringView{ *this }, QStringView{ s }); }
inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s2)
{ return QString::localeAwareCompare(QStringView{ s1 }, QStringView{ s2 }); }
inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
{ return QString::localeAwareCompare(QStringView{ s1 }, QStringView{ s2 }); }
#if QT_STRINGVIEW_LEVEL < 2
inline bool QStringRef::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
#endif
inline bool QStringRef::contains(QLatin1String s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
{ return indexOf(c, 0, cs) != -1; }
inline bool QStringRef::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
{ return indexOf(s, 0, cs) != -1; }
#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
inline QString operator+(const QString &s1, const QStringRef &s2)
{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
inline QString operator+(const QStringRef &s1, const QString &s2)
{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
inline QString operator+(const QStringRef &s1, QLatin1String s2)
{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
inline QString operator+(QLatin1String s1, const QStringRef &s2)
{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
inline QString operator+(const QStringRef &s1, const QStringRef &s2)
{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
inline QString operator+(const QStringRef &s1, QChar s2)
{ QString t; t.reserve(s1.size() + 1); t += s1; t += s2; return t; }
inline QString operator+(QChar s1, const QStringRef &s2)
{ QString t; t.reserve(1 + s2.size()); t += s1; t += s2; return t; }
#endif // !(QT_USE_FAST_OPERATOR_PLUS || QT_USE_QSTRINGBUILDER)
QT_END_NAMESPACE
#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
#include <QtCore/qstringbuilder.h>
QT_BEGIN_NAMESPACE
template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
{
typedef QStringRef type;
typedef QString ConvertTo;
enum { ExactSize = true };
static int size(const QStringRef &a) { return a.size(); }
static inline void appendTo(const QStringRef &a, QChar *&out)
{
const int n = a.size();
if (n)
memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
out += n;
}
};
QT_END_NAMESPACE
#endif
#endif // QSTRINGREF_H

4
src/core5/text/text.pri Normal file
View File

@ -0,0 +1,4 @@
QT += core-private
HEADERS += text/qstringref.h
SOURCES += text/qstringref.cpp
DEFINES += QT_USE_FAST_OPERATOR_PLUS QT_USE_QSTRINGBUILDER

View File

@ -4,3 +4,5 @@ add_subdirectory(qlinkedlist)
add_subdirectory(qregexp)
add_subdirectory(codecs)
add_subdirectory(serialization)
add_subdirectory(text)
add_subdirectory(io)

View File

@ -6,8 +6,8 @@
add_qt_test(tst_utf8
SOURCES
utf8data.h
tst_utf8.cpp
utf8data.h
PUBLIC_LIBRARIES
Qt::Core5Compat
)

View File

@ -3,4 +3,6 @@ SUBDIRS += \
qlinkedlist \
qregexp \
codecs \
serialization
serialization \
text \
io

View File

@ -0,0 +1,3 @@
# Generated from io.pro.
add_subdirectory(qdebug)

View File

@ -0,0 +1,4 @@
TEMPLATE = subdirs
SUBDIRS = \
qdebug

View File

@ -0,0 +1,12 @@
# Generated from qdebug.pro.
#####################################################################
## tst_qdebug Test:
#####################################################################
qt_add_test(tst_qdebug
SOURCES
tst_qdebug.cpp
PUBLIC_LIBRARIES
Qt::Core5Compat
)

View File

@ -0,0 +1,4 @@
CONFIG += testcase
TARGET = tst_qdebug
QT = core testlib core5compat
SOURCES = tst_qdebug.cpp

View File

@ -0,0 +1,119 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/QtDebug>
#include <QtTest/QtTest>
#include <qstringref.h>
class tst_QDebug: public QObject
{
Q_OBJECT
private slots:
void qDebugQStringRef() const;
};
static QtMsgType s_msgType;
static QString s_msg;
static QByteArray s_file;
static int s_line;
static QByteArray s_function;
static void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
s_msg = msg;
s_msgType = type;
s_file = context.file;
s_line = context.line;
s_function = context.function;
}
// Helper class to ensure that the testlib message handler gets
// restored at the end of each test function, even if the test
// fails or throws an exception.
class MessageHandlerSetter
{
public:
MessageHandlerSetter(QtMessageHandler newMessageHandler)
: oldMessageHandler(qInstallMessageHandler(newMessageHandler))
{ }
~MessageHandlerSetter()
{
qInstallMessageHandler(oldMessageHandler);
}
private:
QtMessageHandler oldMessageHandler;
};
void tst_QDebug::qDebugQStringRef() const
{
/* Use a basic string. */
{
QString file, function;
int line = 0;
const QString in(QLatin1String("input"));
const QStringRef inRef(&in);
MessageHandlerSetter mhs(myMessageHandler);
{ qDebug() << inRef; }
#ifndef QT_NO_MESSAGELOGCONTEXT
file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
#endif
QCOMPARE(s_msgType, QtDebugMsg);
QCOMPARE(s_msg, QString::fromLatin1("\"input\""));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
}
/* Use a null QStringRef. */
{
QString file, function;
int line = 0;
const QStringRef inRef;
MessageHandlerSetter mhs(myMessageHandler);
{ qDebug() << inRef; }
#ifndef QT_NO_MESSAGELOGCONTEXT
file = __FILE__; line = __LINE__ - 2; function = Q_FUNC_INFO;
#endif
QCOMPARE(s_msgType, QtDebugMsg);
QCOMPARE(s_msg, QString::fromLatin1("\"\""));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
}
}
QTEST_MAIN(tst_QDebug);
#include "tst_qdebug.moc"

View File

@ -1,3 +1,4 @@
# Generated from serialization.pro.
add_subdirectory(json)
add_subdirectory(qtextstream)

View File

@ -0,0 +1,12 @@
# Generated from qtextstream.pro.
#####################################################################
## tst_qtextstream Test:
#####################################################################
qt_add_test(tst_qtextstream
SOURCES
tst_qtextstream.cpp
PUBLIC_LIBRARIES
Qt::Core5Compat
)

View File

@ -0,0 +1,4 @@
CONFIG += testcase
TARGET = tst_qtextstream
QT = core testlib core5compat
SOURCES = tst_qtextstream.cpp

View File

@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QBuffer>
#include <QStringConverter>
#include <QStringRef>
#include <QTextStream>
class tst_QTextStream : public QObject
{
Q_OBJECT
private slots:
// text write operators
void stringref_write_operator_ToDevice();
};
void tst_QTextStream::stringref_write_operator_ToDevice()
{
QBuffer buf;
buf.open(QBuffer::WriteOnly);
QTextStream stream(&buf);
stream.setEncoding(QStringConverter::Latin1);
stream.setAutoDetectUnicode(true);
const QString expected = "No explicit lengthExplicit length";
stream << QStringRef(&expected).left(18);
stream << QStringRef(&expected).mid(18);
stream.flush();
QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length");
}
QTEST_MAIN(tst_QTextStream)
#include "tst_qtextstream.moc"

View File

@ -1,2 +1,3 @@
TEMPLATE = subdirs
SUBDIRS = json
SUBDIRS = json \
qtextstream

View File

@ -0,0 +1,4 @@
# Generated from text.pro.
add_subdirectory(qstringref)
add_subdirectory(qstringbuilder)

View File

@ -0,0 +1,3 @@
# Generated from qstringbuilder.pro.
add_subdirectory(qstringbuilder1)

View File

@ -0,0 +1,2 @@
TEMPLATE=subdirs
SUBDIRS= qstringbuilder1

View File

@ -0,0 +1,15 @@
# Generated from qstringbuilder1.pro.
#####################################################################
## tst_qstringbuilder1 Test:
#####################################################################
qt_add_test(tst_qstringbuilder1
SOURCES
tst_qstringbuilder1.cpp
DEFINES
QT_USE_FAST_OPERATOR_PLUS
QT_USE_QSTRINGBUILDER
PUBLIC_LIBRARIES
Qt::Core5Compat
)

View File

@ -0,0 +1,5 @@
CONFIG += testcase
TARGET = tst_qstringbuilder1
QT = core testlib core5compat
SOURCES = tst_qstringbuilder1.cpp
DEFINES += QT_USE_FAST_OPERATOR_PLUS QT_USE_QSTRINGBUILDER

View File

@ -0,0 +1,363 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
// Do not include anything in this file. We are being #included with
// a bunch of defines that may break other legitimate code.
#define LITERAL "some literal"
#define LITERAL_LEN (sizeof(LITERAL)-1)
#define LITERAL_EXTRA "some literal" "EXTRA"
// "some literal", but replacing all vowels by their umlauted UTF-8 string :)
#define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l"
#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1)
#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA"
#ifdef Q_COMPILER_UNICODE_STRINGS
// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
#define UNICODE_LITERAL u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l"
#define UNICODE_LITERAL_LEN ((sizeof(UNICODE_LITERAL) - 1) / 2)
#define UNICODE_LITERAL_EXTRA u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l" "EXTRA"
#endif
#ifndef P
# error You need to define P
#endif
//fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS
#ifndef QT_USE_FAST_CONCATENATION
#define Q %
#else
#define Q P
#endif
template <typename T> QString toQString(const T &t);
template <> QString toQString(const QString &s) { return s; }
template <> QString toQString(const QStringRef &r) { return r.toString(); }
template <> QString toQString(const QStringView &v) { return v.toString(); }
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 <size_t N> QString toQString(const char16_t (&a)[N]) { return QStringView(a).toString(); }
template <> QString toQString(const char16_t &c) { return QChar(c); }
#endif
template <typename T> QByteArray toQByteArray(const T &t);
template <> QByteArray toQByteArray(const QByteArray &b) { return b; }
template <> QByteArray toQByteArray(char * const &p) { return p; }
template <size_t N> QByteArray toQByteArray(const char (&a)[N]) { return a; }
template <> QByteArray toQByteArray(const char &c) { return QByteArray(&c, 1); }
void runScenario()
{
// this code is latin1. TODO: replace it with the utf8 block below, once
// strings default to utf8.
QLatin1String l1string(LITERAL);
QString string(l1string);
QStringRef stringref(&string, 2, 10);
QStringView stringview(stringref);
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 { \
DO(QorP, a1, a2); \
DO(QorP, a2, a1); \
} while (0)
#define DO(QorP, a1, a2) \
QCOMPARE(QString(a1 QorP a2), \
toQString(a1).append(toQString(a2))) \
/* end */
CHECK(P, l1string, l1string);
CHECK(P, l1string, string);
CHECK(P, l1string, stringref);
CHECK(Q, l1string, stringview);
CHECK(P, l1string, lchar);
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);
CHECK(Q, string, stringview);
CHECK(P, string, lchar);
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(Q, stringref, stringview);
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(Q, stringview, stringview);
CHECK(Q, stringview, lchar);
CHECK(Q, stringview, qchar);
CHECK(Q, stringview, special);
CHECK(P, stringview, QStringLiteral(LITERAL));
CHECK(Q, stringview, u16char);
CHECK(Q, stringview, u16chararray);
CHECK(Q, stringview, 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
#define DO(QorP, a1, a2) \
QCOMPARE(QByteArray(a1 QorP a2), \
toQByteArray(a1).append(toQByteArray(a2))) \
/* end */
QByteArray bytearray = stringref.toUtf8();
char *charstar = bytearray.data();
char chararray[3] = { 'H', 'i', '\0' };
const char constchararray[3] = { 'H', 'i', '\0' };
char achar = 'a';
CHECK(P, bytearray, bytearray);
CHECK(P, bytearray, charstar);
#ifndef Q_CC_MSVC // see QTBUG-65359
CHECK(P, bytearray, chararray);
#else
Q_UNUSED(chararray);
#endif
CHECK(P, bytearray, constchararray);
CHECK(P, bytearray, achar);
//CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded
//CHECK(Q, charstar, chararray);
//CHECK(Q, charstar, achar);
//CHECK(Q, chararray, chararray); // BUILTIN <-> BUILTIN cat't be overloaded
//CHECK(Q, chararray, achar);
//CHECK(Q, achar, achar); // BUILTIN <-> BUILTIN cat't be overloaded
#undef DO
#undef CHECK
QString r2(QLatin1String(LITERAL LITERAL));
QString r3 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
QString r;
// self-assignment:
r = stringref.toString();
r = lchar + r;
QCOMPARE(r, QString(lchar P stringref));
#ifdef Q_COMPILER_UNICODE_STRINGS
r = QStringLiteral(UNICODE_LITERAL);
r = r Q QStringLiteral(UNICODE_LITERAL);
QCOMPARE(r, r3);
#endif
#ifndef QT_NO_CAST_FROM_ASCII
r = string P LITERAL;
QCOMPARE(r, r2);
r = LITERAL P string;
QCOMPARE(r, r2);
QByteArray ba = QByteArray(LITERAL);
r = ba P string;
QCOMPARE(r, r2);
r = string P ba;
QCOMPARE(r, r2);
r = string P QByteArrayLiteral(LITERAL);
QCOMPARE(r, r2);
r = QByteArrayLiteral(LITERAL) P string;
QCOMPARE(r, r2);
static const char badata[] = LITERAL_EXTRA;
ba = QByteArray::fromRawData(badata, LITERAL_LEN);
r = ba P string;
QCOMPARE(r, r2);
r = string P ba;
QCOMPARE(r, r2);
string = QString::fromUtf8(UTF8_LITERAL);
ba = UTF8_LITERAL;
r = string P UTF8_LITERAL;
QCOMPARE(r.size(), r3.size());
QCOMPARE(r, r3);
r = UTF8_LITERAL P string;
QCOMPARE(r, r3);
r = ba P string;
QCOMPARE(r, r3);
r = string P ba;
QCOMPARE(r, r3);
ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
r = ba P string;
QCOMPARE(r, r3);
r = string P ba;
QCOMPARE(r, r3);
ba = QByteArray(); // empty
r = ba P string;
QCOMPARE(r, string);
r = string P ba;
QCOMPARE(r, string);
const char *zero = 0;
r = string P zero;
QCOMPARE(r, string);
r = zero P string;
QCOMPARE(r, string);
#endif
string = QString::fromLatin1(LITERAL);
QCOMPARE(QByteArray(qPrintable(string P string)), QByteArray(string.toLatin1() + string.toLatin1()));
//QByteArray
{
QByteArray ba = LITERAL;
QByteArray superba = ba P ba P LITERAL;
QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
ba = QByteArrayLiteral(LITERAL);
QCOMPARE(ba, QByteArray(LITERAL));
superba = ba P QByteArrayLiteral(LITERAL) P LITERAL;
QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
QByteArray testWith0 = ba P "test\0with\0zero" P ba;
QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL));
QByteArray ba2 = ba P '\0' + LITERAL;
QCOMPARE(ba2, QByteArray(LITERAL "\0" LITERAL, ba.size()*2+1));
const char *mmh = "test\0foo";
QCOMPARE(QByteArray(ba P mmh P ba), testWith0);
QByteArray raw = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
QByteArray r = "hello" P raw;
QByteArray r2 = "hello" UTF8_LITERAL;
QCOMPARE(r, r2);
r2 = QByteArray("hello\0") P UTF8_LITERAL;
QCOMPARE(r, r2);
const char *zero = 0;
r = ba P zero;
QCOMPARE(r, ba);
r = zero P ba;
QCOMPARE(r, ba);
}
//operator QString +=
{
QString str = QString::fromUtf8(UTF8_LITERAL);
str += QLatin1String(LITERAL) P str;
QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
#ifndef QT_NO_CAST_FROM_ASCII
str = (QString::fromUtf8(UTF8_LITERAL) += QLatin1String(LITERAL) P UTF8_LITERAL);
QCOMPARE(str, QString::fromUtf8(UTF8_LITERAL LITERAL UTF8_LITERAL));
#endif
QString str2 = QString::fromUtf8(UTF8_LITERAL);
QString str2_e = QString::fromUtf8(UTF8_LITERAL);
const char * nullData = 0;
str2 += QLatin1String(nullData) P str2;
str2_e += QLatin1String("") P str2_e;
QCOMPARE(str2, str2_e);
}
//operator QByteArray +=
{
QByteArray ba = UTF8_LITERAL;
ba += QByteArray(LITERAL) P UTF8_LITERAL;
QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL));
ba += LITERAL P QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
QCOMPARE(ba, QByteArray(UTF8_LITERAL LITERAL UTF8_LITERAL LITERAL UTF8_LITERAL));
QByteArray withZero = QByteArray(LITERAL "\0" LITERAL, LITERAL_LEN*2+1);
QByteArray ba2 = withZero;
ba2 += ba2 P withZero;
QCOMPARE(ba2, QByteArray(withZero + withZero + withZero));
}
}

View File

@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qglobal.h>
// SCENARIO 1
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * defined
#undef QT_USE_QSTRINGBUILDER
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QStringBuilder>
#include <QtTest/QTest>
#include <qstringref.h>
#define LITERAL "some literal"
void runScenario(); // Defined in stringbuilder.cpp #included below.
class tst_QStringBuilder1 : public QObject
{
Q_OBJECT
private slots:
void scenario() { runScenario(); }
};
#define P %
#include "stringbuilder.cpp"
#undef P
#include "tst_qstringbuilder1.moc"
QTEST_APPLESS_MAIN(tst_QStringBuilder1)

View File

@ -0,0 +1,12 @@
# Generated from qstringref.pro.
#####################################################################
## tst_qstringref Test:
#####################################################################
qt_add_test(tst_qstringref
SOURCES
tst_qstringref.cpp
PUBLIC_LIBRARIES
Qt::Core5Compat
)

View File

@ -0,0 +1,4 @@
CONFIG += testcase
TARGET = tst_qstringref
QT = core core5compat testlib
SOURCES = tst_qstringref.cpp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
TEMPLATE = subdirs
SUBDIRS = \
qstringref \
qstringbuilder

View File

@ -0,0 +1,19 @@
# Generated from qstringbuilder.pro.
#####################################################################
## tst_bench_qstringbuilder Binary:
#####################################################################
qt_add_benchmark(tst_bench_qstringbuilder
SOURCES
main.cpp
PUBLIC_LIBRARIES
Qt::Core5Compat
Qt::Test
COMPILE_OPTIONS
-g
)
#### Keys ignored in scope 1:.:.:qstringbuilder.pro:<TRUE>:
# QMAKE_CFLAGS = "-g"
# TEMPLATE = "app"

View File

@ -0,0 +1,429 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
// Select one of the scenarios below
#define SCENARIO 1
#if SCENARIO == 1
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * defined
#undef QT_USE_FAST_OPERATOR_PLUS
#undef QT_USE_FAST_CONCATENATION
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif
#if SCENARIO == 2
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * defined
#define QT_USE_FAST_OPERATOR_PLUS
#define QT_USE_FAST_CONCATENATION
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif
#if SCENARIO == 3
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * _not_ defined
#undef QT_USE_FAST_OPERATOR_PLUS
#undef QT_USE_FAST_CONCATENATION
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#endif
#if SCENARIO == 4
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * _not_ defined
#define QT_USE_FAST_OPERATOR_PLUS
#define QT_USE_FAST_CONCATENATION
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#endif
#include <qbytearray.h>
#include <qdebug.h>
#include <qstring.h>
#include <qstringbuilder.h>
#include <qtest.h>
#include <string>
// Select one of the scenarios below
#if SCENARIO == 1
#define P %
#elif SCENARIO == 2
#define P +
#elif SCENARIO == 3
#define P %
#elif SCENARIO == 4
#define P +
#endif
#define COMPARE(a, b) QCOMPARE(a, b)
//#define COMPARE(a, b)
#define SEP(s) qDebug() << "\n\n-------- " s " ---------";
#define LITERAL "some string literal"
class tst_qstringbuilder : public QObject
{
Q_OBJECT
public:
tst_qstringbuilder()
: l1literal(LITERAL),
l1string(LITERAL),
ba(LITERAL),
string(l1string),
stdstring(LITERAL),
stringref(&string, 2, 10),
achar('c'),
r2(QLatin1String(LITERAL LITERAL)),
r3(QLatin1String(LITERAL LITERAL LITERAL)),
r4(QLatin1String(LITERAL LITERAL LITERAL LITERAL)),
r5(QLatin1String(LITERAL LITERAL LITERAL LITERAL LITERAL))
{}
public:
enum { N = 10000 };
int run_traditional()
{
int s = 0;
for (int i = 0; i < N; ++i) {
#if 0
s += QString(l1string + l1string).size();
s += QString(l1string + l1string + l1string).size();
s += QString(l1string + l1string + l1string + l1string).size();
s += QString(l1string + l1string + l1string + l1string + l1string).size();
#endif
s += QString(achar + l1string + achar).size();
}
return s;
}
int run_builder()
{
int s = 0;
for (int i = 0; i < N; ++i) {
#if 0
s += QString(l1literal P l1literal).size();
s += QString(l1literal P l1literal P l1literal).size();
s += QString(l1literal P l1literal P l1literal P l1literal).size();
s += QString(l1literal P l1literal P l1literal P l1literal P l1literal).size();
#endif
s += QString(achar % l1literal % achar).size();
}
return s;
}
private slots:
void separator_0() {
qDebug() << "\nIn each block the QStringBuilder based result appear first "
"(with a 'b_' prefix), QStringBased second ('q_' prefix), std::string "
"last ('s_' prefix)\n";
}
void separator_1() { SEP("literal + literal (builder first)"); }
void b_2_l1literal() {
QBENCHMARK { r = l1literal P l1literal; }
COMPARE(r, r2);
}
#ifndef QT_NO_CAST_FROM_ASCII
void b_l1literal_LITERAL() {
QBENCHMARK { r = l1literal P LITERAL; }
COMPARE(r, r2);
}
#endif
void q_2_l1string() {
QBENCHMARK { r = l1string + l1string; }
COMPARE(r, r2);
}
void separator_2() { SEP("2 strings"); }
void b_2_string() {
QBENCHMARK { r = string P string; }
COMPARE(r, r2);
}
void q_2_string() {
QBENCHMARK { r = string + string; }
COMPARE(r, r2);
}
void s_2_string() {
QBENCHMARK { stdr = stdstring + stdstring; }
COMPARE(stdr, stdstring + stdstring);
}
void separator_2c() { SEP("2 string refs"); }
void b_2_stringref() {
QBENCHMARK { r = stringref % stringref; }
COMPARE(r, QString(stringref.toString() + stringref.toString()));
}
void q_2_stringref() {
QBENCHMARK { r = stringref.toString() + stringref.toString(); }
COMPARE(r, QString(stringref % stringref));
}
void separator_2b() { SEP("3 strings"); }
void b_3_string() {
QBENCHMARK { r = string P string P string; }
COMPARE(r, r3);
}
void q_3_string() {
QBENCHMARK { r = string + string + string; }
COMPARE(r, r3);
}
void s_3_string() {
QBENCHMARK { stdr = stdstring + stdstring + stdstring; }
COMPARE(stdr, stdstring + stdstring + stdstring);
}
void separator_2e() { SEP("4 strings"); }
void b_4_string() {
QBENCHMARK { r = string P string P string P string; }
COMPARE(r, r4);
}
void q_4_string() {
QBENCHMARK { r = string + string + string + string; }
COMPARE(r, r4);
}
void s_4_string() {
QBENCHMARK { stdr = stdstring + stdstring + stdstring + stdstring; }
COMPARE(stdr, stdstring + stdstring + stdstring + stdstring);
}
void separator_2a() { SEP("string + literal (builder first)"); }
void b_string_l1literal() {
QBENCHMARK { r = string % l1literal; }
COMPARE(r, r2);
}
#ifndef QT_NO_CAST_FROM_ASCII
void b_string_LITERAL() {
QBENCHMARK { r = string P LITERAL; }
COMPARE(r, r2);
}
void b_LITERAL_string() {
QBENCHMARK { r = LITERAL P string; }
COMPARE(r, r2);
}
#endif
void b_string_l1string() {
QBENCHMARK { r = string P l1string; }
COMPARE(r, r2);
}
void q_string_l1literal() {
QBENCHMARK { r = string + l1string; }
COMPARE(r, r2);
}
void q_string_l1string() {
QBENCHMARK { r = string + l1string; }
COMPARE(r, r2);
}
void s_LITERAL_string() {
QBENCHMARK { stdr = LITERAL + stdstring; }
COMPARE(stdr, stdstring + stdstring);
}
void separator_3() { SEP("3 literals"); }
void b_3_l1literal() {
QBENCHMARK { r = l1literal P l1literal P l1literal; }
COMPARE(r, r3);
}
void q_3_l1string() {
QBENCHMARK { r = l1string + l1string + l1string; }
COMPARE(r, r3);
}
void s_3_l1string() {
QBENCHMARK { stdr = stdstring + LITERAL + LITERAL; }
COMPARE(stdr, stdstring + stdstring + stdstring);
}
void separator_4() { SEP("4 literals"); }
void b_4_l1literal() {
QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal; }
COMPARE(r, r4);
}
void q_4_l1string() {
QBENCHMARK { r = l1string + l1string + l1string + l1string; }
COMPARE(r, r4);
}
void separator_5() { SEP("5 literals"); }
void b_5_l1literal() {
QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal P l1literal; }
COMPARE(r, r5);
}
void q_5_l1string() {
QBENCHMARK { r = l1string + l1string + l1string + l1string + l1string; }
COMPARE(r, r5);
}
void separator_6() { SEP("4 chars"); }
void b_string_4_char() {
QBENCHMARK { r = string + achar + achar + achar + achar; }
COMPARE(r, QString(string P achar P achar P achar P achar));
}
void q_string_4_char() {
QBENCHMARK { r = string + achar + achar + achar + achar; }
COMPARE(r, QString(string P achar P achar P achar P achar));
}
void s_string_4_char() {
QBENCHMARK { stdr = stdstring + 'c' + 'c' + 'c' + 'c'; }
COMPARE(stdr, stdstring + 'c' + 'c' + 'c' + 'c');
}
void separator_7() { SEP("char + string + char"); }
void b_char_string_char() {
QBENCHMARK { r = achar + string + achar; }
COMPARE(r, QString(achar P string P achar));
}
void q_char_string_char() {
QBENCHMARK { r = achar + string + achar; }
COMPARE(r, QString(achar P string P achar));
}
void s_char_string_char() {
QBENCHMARK { stdr = 'c' + stdstring + 'c'; }
COMPARE(stdr, 'c' + stdstring + 'c');
}
void separator_8() { SEP("string.arg"); }
void b_string_arg() {
const QString pattern = l1string + QString::fromLatin1("%1") + l1string;
QBENCHMARK { r = l1literal P string P l1literal; }
COMPARE(r, r3);
}
void q_string_arg() {
const QString pattern = l1string + QLatin1String("%1") + l1string;
QBENCHMARK { r = pattern.arg(string); }
COMPARE(r, r3);
}
void q_bytearray_arg() {
QByteArray result;
QBENCHMARK { result = ba + ba + ba; }
}
void separator_9() { SEP("QString::reserve()"); }
void b_reserve() {
QBENCHMARK {
r.clear();
r = string P string P string P string;
}
COMPARE(r, r4);
}
void b_reserve_lit() {
QBENCHMARK {
r.clear();
r = string P l1literal P string P string;
}
COMPARE(r, r4);
}
void s_reserve() {
QBENCHMARK {
r.clear();
r.reserve(string.size() + string.size() + string.size() + string.size());
r += string;
r += string;
r += string;
r += string;
}
COMPARE(r, r4);
}
void s_reserve_lit() {
QBENCHMARK {
r.clear();
//r.reserve(string.size() + qstrlen(l1string.latin1())
// + string.size() + string.size());
r.reserve(1024);
r += string;
r += l1string;
r += string;
r += string;
}
COMPARE(r, r4);
}
private:
const QLatin1String l1literal;
const QLatin1String l1string;
const QByteArray ba;
const QString string;
const std::string stdstring;
const QStringRef stringref;
const QLatin1Char achar;
const QString r2, r3, r4, r5;
// short cuts for results
QString r;
std::string stdr;
};
QTEST_MAIN(tst_qstringbuilder)
#undef P
#include "main.moc"

View File

@ -0,0 +1,9 @@
TEMPLATE = app
CONFIG += benchmark
QT = core testlib core5compat
QMAKE_CXXFLAGS += -g
QMAKE_CFLAGS += -g
TARGET = tst_bench_qstringbuilder
SOURCES += main.cpp