Get rid of QCharRef and QByteRef

We already detach immediately since change
c2d2757bcc. That basically removes
the main purpose of having QChar/ByteRef, and we can just as well
get rid of those classes for Qt 6.

Change-Id: I8dc566a1948ddc29c0cb8a77ec7310654a7219a4
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
bb10
Lars Knoll 2019-11-13 09:29:42 +01:00
parent 7cc977759b
commit 063e39df13
11 changed files with 25 additions and 347 deletions

View File

@ -29,7 +29,7 @@
\dontdocument (QMacAutoReleasePool QIncompatibleFlag QGenericAtomicOps QAtomicTraits
QAtomicOps QBasicAtomicInteger QBasicAtomicPointer QBasicMutex QInternal
QArgument QReturnArgument QArrayData QTypedArrayData QStaticByteArrayData
QByteRef QStaticStringData QListSpecialMethods QListData QScopedPointerDeleter
QStaticStringData QListSpecialMethods QListData QScopedPointerDeleter
QScopedPointerArrayDeleter QScopedPointerPodDeleter QScopedPointerObjectDeleteLater
QMetaTypeId2 QObjectData QObjectUserData QMapNodeBase QMapNode QMapDataBase
QMapData QHashData QHashNode QArrayDataPointer QTextStreamManipulator

View File

@ -1423,7 +1423,7 @@ QByteArray &QByteArray::operator=(const char *str)
\sa operator[]()
*/
/*! \fn QByteRef QByteArray::operator[](int i)
/*! \fn char &QByteArray::operator[](int i)
Returns the byte at index position \a i as a modifiable reference.
@ -1434,21 +1434,6 @@ QByteArray &QByteArray::operator=(const char *str)
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 9
The return value is of type QByteRef, a helper class for
QByteArray. When you get an object of type QByteRef, you can use
it as if it were a char &. If you assign to it, the assignment
will apply to the character in the QByteArray from which you got
the reference.
\note Before Qt 5.14 it was possible to use this operator to access
a character at an out-of-bounds position in the byte array, and
then assign to such a position, causing the byte array to be
automatically resized. Furthermore, assigning a value to the
returned QByteRef would cause a detach of the byte array, even if the
byte array has been copied in the meanwhile (and the QByteRef kept
alive while the copy was taken). These behaviors are deprecated,
and will be changed in a future version of Qt.
\sa at()
*/
@ -1490,7 +1475,7 @@ QByteArray &QByteArray::operator=(const char *str)
*/
/*!
\fn QByteRef QByteArray::front()
\fn char &QByteArray::front()
\since 5.10
Returns a reference to the first character in the byte array.
@ -1505,7 +1490,7 @@ QByteArray &QByteArray::operator=(const char *str)
*/
/*!
\fn QByteRef QByteArray::back()
\fn char &QByteArray::back()
\since 5.10
Returns a reference to the last character in the byte array.
@ -4904,41 +4889,4 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA
\sa QStringLiteral
*/
namespace QtPrivate {
namespace DeprecatedRefClassBehavior {
void warn(WarningType w, EmittingClass c)
{
static const char deprecatedBehaviorString[] =
"The corresponding behavior is deprecated, and will be changed"
" in a future version of Qt.";
const char *emittingClassName = nullptr;
const char *containerClassName = nullptr;
switch (c) {
case EmittingClass::QByteRef:
emittingClassName = "QByteRef";
containerClassName = "QByteArray";
break;
case EmittingClass::QCharRef:
emittingClassName = "QCharRef";
containerClassName = "QString";
break;
}
switch (w) {
case WarningType::OutOfRange:
qWarning("Using %s with an index pointing outside the valid range of a %s. %s",
emittingClassName, containerClassName, deprecatedBehaviorString);
break;
case WarningType::DelayedDetach:
qWarning("Using %s with on a %s that is not already detached. %s",
emittingClassName, containerClassName, deprecatedBehaviorString);
break;
}
}
} // namespace DeprecatedRefClassBehavior
} // namespace QtPrivate
QT_END_NAMESPACE

View File

@ -110,7 +110,6 @@ Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt, ...);
Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len,
Qt::ChecksumType standard = Qt::ChecksumIso3309);
class QByteRef;
class QString;
class QDataStream;
@ -191,11 +190,11 @@ public:
inline char at(int i) const;
inline char operator[](int i) const;
Q_REQUIRED_RESULT inline QByteRef operator[](int i);
Q_REQUIRED_RESULT inline char &operator[](int i);
Q_REQUIRED_RESULT char front() const { return at(0); }
Q_REQUIRED_RESULT inline QByteRef front();
Q_REQUIRED_RESULT inline char &front();
Q_REQUIRED_RESULT char back() const { return at(size() - 1); }
Q_REQUIRED_RESULT inline QByteRef back();
Q_REQUIRED_RESULT inline char &back();
int indexOf(char c, int from = 0) const;
int indexOf(const char *c, int from = 0) const;
@ -439,7 +438,6 @@ private:
static QByteArray simplified_helper(const QByteArray &a);
static QByteArray simplified_helper(QByteArray &a);
friend class QByteRef;
friend class QString;
friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes);
public:
@ -503,83 +501,10 @@ inline void QByteArray::squeeze()
}
}
namespace QtPrivate {
namespace DeprecatedRefClassBehavior {
enum class EmittingClass {
QByteRef,
QCharRef,
};
enum class WarningType {
OutOfRange,
DelayedDetach,
};
Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void warn(WarningType w, EmittingClass c);
} // namespace DeprecatedAssignmentOperatorBehavior
} // namespace QtPrivate
class
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_CORE_EXPORT
#endif
QByteRef { // ### Qt 7: remove
QByteArray &a;
int i;
inline QByteRef(QByteArray &array, int idx)
: a(array),i(idx) {}
friend class QByteArray;
public:
inline operator char() const
{
using namespace QtPrivate::DeprecatedRefClassBehavior;
if (Q_LIKELY(i < a.size()))
return a.constData()[i];
#ifdef QT_DEBUG
warn(WarningType::OutOfRange, EmittingClass::QByteRef);
#endif
return char(0);
}
inline QByteRef &operator=(char c)
{
using namespace QtPrivate::DeprecatedRefClassBehavior;
if (Q_UNLIKELY(i >= a.size())) {
#ifdef QT_DEBUG
warn(WarningType::OutOfRange, EmittingClass::QByteRef);
#endif
a.expand(i);
} else {
#ifdef QT_DEBUG
if (Q_UNLIKELY(!a.isDetached()))
warn(WarningType::DelayedDetach, EmittingClass::QByteRef);
#endif
a.detach();
}
a.d.b[i] = c;
return *this;
}
inline QByteRef &operator=(const QByteRef &c)
{
return operator=(char(c));
}
inline bool operator==(char c) const
{ return a.data()[i] == c; }
inline bool operator!=(char c) const
{ return a.data()[i] != c; }
inline bool operator>(char c) const
{ return a.data()[i] > c; }
inline bool operator>=(char c) const
{ return a.data()[i] >= c; }
inline bool operator<(char c) const
{ return a.data()[i] < c; }
inline bool operator<=(char c) const
{ return a.data()[i] <= c; }
};
inline QByteRef QByteArray::operator[](int i)
{ Q_ASSERT(i >= 0); detach(); return QByteRef(*this, i); }
inline QByteRef QByteArray::front() { return operator[](0); }
inline QByteRef QByteArray::back() { return operator[](size() - 1); }
inline char &QByteArray::operator[](int i)
{ Q_ASSERT(i >= 0 && i < size()); return data()[i]; }
inline char &QByteArray::front() { return operator[](0); }
inline char &QByteArray::back() { return operator[](size() - 1); }
inline QByteArray::iterator QByteArray::begin()
{ return data(); }
inline QByteArray::const_iterator QByteArray::begin() const

View File

@ -439,7 +439,6 @@ public:
Unicode_12_0,
Unicode_12_1
};
// ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
inline Category category() const noexcept { return QChar::category(ucs); }
inline Direction direction() const noexcept { return QChar::direction(ucs); }

View File

@ -1359,28 +1359,6 @@ const QString::Null QString::null = { };
\sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII
*/
/*!
\class QCharRef
\inmodule QtCore
\reentrant
\brief The QCharRef class is a helper class for QString.
\internal
\ingroup string-processing
When you get an object of type QCharRef, if you can assign to it,
the assignment will apply to the character in the string from
which you got the reference. That is its whole purpose in life.
The QCharRef becomes invalid once modifications are made to the
string: if you want to keep the character, copy it into a QChar.
Most of the QChar member functions also exist in QCharRef.
However, they are not explicitly documented here.
\sa QString::operator[](), QString::at(), QChar
*/
/*!
\class QString
\inmodule QtCore
@ -5737,7 +5715,7 @@ QString QString::trimmed_helper(QString &str)
*/
/*!
\fn QCharRef QString::operator[](int position)
\fn QChar &QString::operator[](int position)
Returns the character at the specified \a position in the string as a
modifiable reference.
@ -5746,20 +5724,6 @@ QString QString::trimmed_helper(QString &str)
\snippet qstring/main.cpp 85
The return value is of type QCharRef, a helper class for QString.
When you get an object of type QCharRef, you can use it as if it
were a reference to a QChar. If you assign to it, the assignment will apply to
the character in the QString from which you got the reference.
\note Before Qt 5.14 it was possible to use this operator to access
a character at an out-of-bounds position in the string, and
then assign to such a position, causing the string to be
automatically resized. Furthermore, assigning a value to the
returned QCharRef would cause a detach of the string, even if the
string has been copied in the meanwhile (and the QCharRef kept
alive while the copy was taken). These behaviors are deprecated,
and will be changed in a future version of Qt.
\sa at()
*/
@ -5800,7 +5764,7 @@ QString QString::trimmed_helper(QString &str)
*/
/*!
\fn QCharRef QString::front()
\fn QChar &QString::front()
\since 5.10
Returns a reference to the first character in the string.
@ -5815,7 +5779,7 @@ QString QString::trimmed_helper(QString &str)
*/
/*!
\fn QCharRef QString::back()
\fn QChar &QString::back()
\since 5.10
Returns a reference to the last character in the string.

View File

@ -70,7 +70,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
QT_BEGIN_NAMESPACE
class QCharRef;
class QRegExp;
class QRegularExpression;
class QRegularExpressionMatch;
@ -290,12 +289,12 @@ public:
inline const QChar at(int i) const;
const QChar operator[](int i) const;
Q_REQUIRED_RESULT QCharRef operator[](int i);
Q_REQUIRED_RESULT QChar &operator[](int i);
Q_REQUIRED_RESULT inline QChar front() const { return at(0); }
Q_REQUIRED_RESULT inline QCharRef front();
Q_REQUIRED_RESULT inline QChar &front();
Q_REQUIRED_RESULT inline QChar back() const { return at(size() - 1); }
Q_REQUIRED_RESULT inline QCharRef back();
Q_REQUIRED_RESULT inline QChar &back();
Q_REQUIRED_RESULT QString arg(qlonglong a, int fieldwidth=0, int base=10,
QChar fillChar = QLatin1Char(' ')) const;
@ -979,7 +978,6 @@ private:
static qlonglong toIntegral_helper(const QChar *data, int len, bool *ok, int base);
static qulonglong toIntegral_helper(const QChar *data, uint len, bool *ok, int base);
void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen);
friend class QCharRef;
friend class QTextCodec;
friend class QStringRef;
friend class QStringView;
@ -1131,128 +1129,6 @@ inline QString QString::fromWCharArray(const wchar_t *string, int size)
: fromUcs4(reinterpret_cast<const uint *>(string), size);
}
class
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_CORE_EXPORT
#endif
QCharRef { // ### Qt 7: remove
QString &s;
int i;
inline QCharRef(QString &str, int idx)
: s(str),i(idx) {}
friend class QString;
public:
// most QChar operations repeated here
// all this is not documented: We just say "like QChar" and let it be.
inline operator QChar() const
{
using namespace QtPrivate::DeprecatedRefClassBehavior;
if (Q_LIKELY(i < s.size()))
return QChar(s.constData()[i]);
#ifdef QT_DEBUG
warn(WarningType::OutOfRange, EmittingClass::QCharRef);
#endif
return QChar();
}
inline QCharRef &operator=(QChar c)
{
using namespace QtPrivate::DeprecatedRefClassBehavior;
if (Q_UNLIKELY(i >= s.size())) {
#ifdef QT_DEBUG
warn(WarningType::OutOfRange, EmittingClass::QCharRef);
#endif
s.resize(i + 1, QLatin1Char(' '));
} else {
#ifdef QT_DEBUG
if (Q_UNLIKELY(!s.isDetached()))
warn(WarningType::DelayedDetach, EmittingClass::QCharRef);
#endif
s.detach();
}
s.d.b[i] = c.unicode();
return *this;
}
// An operator= for each QChar cast constructors
#ifndef QT_NO_CAST_FROM_ASCII
inline QT_ASCII_CAST_WARN QCharRef &operator=(char c)
{ return operator=(QChar::fromLatin1(c)); }
inline QT_ASCII_CAST_WARN QCharRef &operator=(uchar c)
{ return operator=(QChar::fromLatin1(c)); }
#endif
inline QCharRef &operator=(const QCharRef &c) { return operator=(QChar(c)); }
inline QCharRef &operator=(ushort rc) { return operator=(QChar(rc)); }
inline QCharRef &operator=(short rc) { return operator=(QChar(rc)); }
inline QCharRef &operator=(uint rc) { return operator=(QChar(rc)); }
inline QCharRef &operator=(int rc) { return operator=(QChar(rc)); }
// each function...
inline bool isNull() const { return QChar(*this).isNull(); }
inline bool isPrint() const { return QChar(*this).isPrint(); }
inline bool isPunct() const { return QChar(*this).isPunct(); }
inline bool isSpace() const { return QChar(*this).isSpace(); }
inline bool isMark() const { return QChar(*this).isMark(); }
inline bool isLetter() const { return QChar(*this).isLetter(); }
inline bool isNumber() const { return QChar(*this).isNumber(); }
inline bool isLetterOrNumber() { return QChar(*this).isLetterOrNumber(); }
inline bool isDigit() const { return QChar(*this).isDigit(); }
inline bool isLower() const { return QChar(*this).isLower(); }
inline bool isUpper() const { return QChar(*this).isUpper(); }
inline bool isTitleCase() const { return QChar(*this).isTitleCase(); }
inline int digitValue() const { return QChar(*this).digitValue(); }
QChar toLower() const { return QChar(*this).toLower(); }
QChar toUpper() const { return QChar(*this).toUpper(); }
QChar toTitleCase () const { return QChar(*this).toTitleCase(); }
QChar::Category category() const { return QChar(*this).category(); }
QChar::Direction direction() const { return QChar(*this).direction(); }
QChar::JoiningType joiningType() const { return QChar(*this).joiningType(); }
#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED QChar::Joining joining() const
{
switch (QChar(*this).joiningType()) {
case QChar::Joining_Causing: return QChar::Center;
case QChar::Joining_Dual: return QChar::Dual;
case QChar::Joining_Right: return QChar::Right;
case QChar::Joining_None:
case QChar::Joining_Left:
case QChar::Joining_Transparent:
default: return QChar::OtherJoining;
}
}
#endif
bool hasMirrored() const { return QChar(*this).hasMirrored(); }
QChar mirroredChar() const { return QChar(*this).mirroredChar(); }
QString decomposition() const { return QChar(*this).decomposition(); }
QChar::Decomposition decompositionTag() const { return QChar(*this).decompositionTag(); }
uchar combiningClass() const { return QChar(*this).combiningClass(); }
inline QChar::Script script() const { return QChar(*this).script(); }
QChar::UnicodeVersion unicodeVersion() const { return QChar(*this).unicodeVersion(); }
inline uchar cell() const { return QChar(*this).cell(); }
inline uchar row() const { return QChar(*this).row(); }
inline void setCell(uchar cell);
inline void setRow(uchar row);
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED char toAscii() const { return QChar(*this).toLatin1(); }
#endif
char toLatin1() const { return QChar(*this).toLatin1(); }
ushort unicode() const { return QChar(*this).unicode(); }
ushort& unicode() { return s.data()[i].unicode(); }
};
Q_DECLARE_TYPEINFO(QCharRef, Q_MOVABLE_TYPE);
inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
inline QString::QString() noexcept { d.d = Data::sharedNull(); d.b = Data::sharedNullData(); d.size = 0; }
inline QString::~QString() { if (!d.d->deref()) Data::deallocate(d.d); }
@ -1278,10 +1154,10 @@ inline void QString::squeeze()
inline QString &QString::setUtf16(const ushort *autf16, int asize)
{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
inline QCharRef QString::operator[](int i)
{ Q_ASSERT(i >= 0); detach(); return QCharRef(*this, i); }
inline QCharRef QString::front() { return operator[](0); }
inline QCharRef QString::back() { return operator[](size() - 1); }
inline QChar &QString::operator[](int i)
{ Q_ASSERT(i >= 0 && i < size()); return data()[i]; }
inline QChar &QString::front() { return operator[](0); }
inline QChar &QString::back() { return operator[](size() - 1); }
inline QString::iterator QString::begin()
{ detach(); return reinterpret_cast<QChar*>(d.b); }
inline QString::const_iterator QString::begin() const

View File

@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
\list
\li QString, QStringRef, (since 5.10:) QStringView
\li QChar, QCharRef, QLatin1Char, (since 5.10:) \c char16_t,
\li QChar, 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[]}.
@ -108,7 +108,7 @@ QT_BEGIN_NAMESPACE
This function is usable with arguments of type \c QString,
\c QLatin1String, \c QStringRef,
\c QChar, \c QCharRef, \c QLatin1Char, and \c char.
\c QChar, \c QLatin1Char, and \c char.
*/
/* \fn template <typename A, typename B> QByteArray QStringBuilder<A, B>::toLatin1() const

View File

@ -231,16 +231,6 @@ template <> struct QConcatenable<QChar::SpecialCharacter> : private QAbstractCon
{ *out++ = c; }
};
template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable
{
typedef QCharRef type;
typedef QString ConvertTo;
enum { ExactSize = true };
static int size(QCharRef) { return 1; }
static inline void appendTo(QCharRef c, QChar *&out)
{ *out++ = QChar(c); }
};
template <> struct QConcatenable<QLatin1String> : private QAbstractConcatenable
{
typedef QLatin1String type;

View File

@ -2003,7 +2003,7 @@ void tst_QByteArray::byteRefDetaching() const
{
{
QByteArray str = "str";
QByteArray copy;
QByteArray copy = str;
copy[0] = 'S';
QCOMPARE(str, QByteArray("str"));

View File

@ -983,28 +983,6 @@ void tst_QString::acc_01()
f[7]='F';
QCOMPARE(text[7],'!');
a="";
a[0]='A';
QCOMPARE(a, QLatin1String("A"));
QCOMPARE(a.length(),1);
a[1]='B';
QCOMPARE(a, QLatin1String("AB"));
QCOMPARE(a.length(),2);
a[2]='C';
QCOMPARE(a, QLatin1String("ABC"));
QCOMPARE(a.length(),3);
a = QString();
QVERIFY(a.isNull());
a[0]='A';
QCOMPARE(a, QLatin1String("A"));
QCOMPARE(a.length(),1);
a[1]='B';
QCOMPARE(a, QLatin1String("AB"));
QCOMPARE(a.length(),2);
a[2]='C';
QCOMPARE(a, QLatin1String("ABC"));
QCOMPARE(a.length(),3);
a="123";
b="456";
a[0]=a[1];
@ -6415,7 +6393,7 @@ void tst_QString::QCharRefDetaching() const
{
{
QString str = QString::fromLatin1("str");
QString copy;
QString copy = str;
copy[0] = QLatin1Char('S');
QCOMPARE(str, QString::fromLatin1("str"));

View File

@ -795,8 +795,6 @@ template <> QStringView make(int size) { return QStringView(s_string).left(siz
template <> QLatin1String make(int size) { return QLatin1String("\1\2\3\4\5\6\7", size); }
template <typename T> T clean(T &&t) { return std::forward<T>(t); }
inline QChar clean(QCharRef ch) { return ch; }
inline char clean(QByteRef ch) { return ch; }
inline char clean(QLatin1Char ch) { return ch.toLatin1(); }
template <typename Container>