QString: add QStringView/QLatin1String overload of (non-multi) arg()
Use the new overload directly in QXmlStream*. Saves 129B in QtCore text size on optimized GCC 6.1 Linux AMD64 builds, even though we added two more functions. [ChangeLog][QtCore][QString] Added arg(QStringView), arg(QLatin1String) overloads. Change-Id: Idf7236dcab763824593f34182e4e0b16b5ed4321 Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
0a5b610679
commit
e1e6506c8d
@ -262,6 +262,17 @@ void Widget::argFunction()
|
||||
.arg(i).arg(total).arg(fileName);
|
||||
//! [11]
|
||||
|
||||
{
|
||||
//! [11]
|
||||
int i; // current file's number
|
||||
int total; // number of files to process
|
||||
QStringView fileName; // current file's name
|
||||
|
||||
QString status = QString("Processing file %1 of %2: %3")
|
||||
.arg(i).arg(total).arg(fileName);
|
||||
//! [11]
|
||||
}
|
||||
|
||||
//! [12] //! [13]
|
||||
QString str;
|
||||
//! [12]
|
||||
|
@ -7363,10 +7363,10 @@ struct ArgEscapeData
|
||||
int escape_len; // total length of escape sequences which will be replaced
|
||||
};
|
||||
|
||||
static ArgEscapeData findArgEscapes(const QString &s)
|
||||
static ArgEscapeData findArgEscapes(QStringView s)
|
||||
{
|
||||
const QChar *uc_begin = s.unicode();
|
||||
const QChar *uc_end = uc_begin + s.length();
|
||||
const QChar *uc_begin = s.begin();
|
||||
const QChar *uc_end = s.end();
|
||||
|
||||
ArgEscapeData d;
|
||||
|
||||
@ -7425,11 +7425,11 @@ static ArgEscapeData findArgEscapes(const QString &s)
|
||||
return d;
|
||||
}
|
||||
|
||||
static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int field_width,
|
||||
const QString &arg, const QString &larg, QChar fillChar = QLatin1Char(' '))
|
||||
static QString replaceArgEscapes(QStringView s, const ArgEscapeData &d, int field_width,
|
||||
QStringView arg, QStringView larg, QChar fillChar)
|
||||
{
|
||||
const QChar *uc_begin = s.unicode();
|
||||
const QChar *uc_end = uc_begin + s.length();
|
||||
const QChar *uc_begin = s.begin();
|
||||
const QChar *uc_end = s.end();
|
||||
|
||||
int abs_field_width = qAbs(field_width);
|
||||
int result_len = s.length()
|
||||
@ -7493,11 +7493,11 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f
|
||||
}
|
||||
|
||||
if (locale_arg) {
|
||||
memcpy(rc, larg.unicode(), larg.length()*sizeof(QChar));
|
||||
memcpy(rc, larg.data(), larg.length()*sizeof(QChar));
|
||||
rc += larg.length();
|
||||
}
|
||||
else {
|
||||
memcpy(rc, arg.unicode(), arg.length()*sizeof(QChar));
|
||||
memcpy(rc, arg.data(), arg.length()*sizeof(QChar));
|
||||
rc += arg.length();
|
||||
}
|
||||
|
||||
@ -7519,6 +7519,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f
|
||||
return result;
|
||||
}
|
||||
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
/*!
|
||||
Returns a copy of this string with the lowest numbered place marker
|
||||
replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99.
|
||||
@ -7549,17 +7550,86 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f
|
||||
in the range 1 to 99.
|
||||
*/
|
||||
QString QString::arg(const QString &a, int fieldWidth, QChar fillChar) const
|
||||
{
|
||||
return arg(QStringView(a), fieldWidth, fillChar);
|
||||
}
|
||||
#endif // QT_STRINGVIEW_LEVEL < 2
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 5.10
|
||||
|
||||
Returns a copy of this string with the lowest-numbered place-marker
|
||||
replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99.
|
||||
|
||||
\a fieldWidth specifies the minimum amount of space that \a a
|
||||
shall occupy. If \a a requires less space than \a fieldWidth, it
|
||||
is padded to \a fieldWidth with character \a fillChar. A positive
|
||||
\a fieldWidth produces right-aligned text. A negative \a fieldWidth
|
||||
produces left-aligned text.
|
||||
|
||||
This example shows how we might create a \c status string for
|
||||
reporting progress while processing a list of files:
|
||||
|
||||
\snippet qstring/main.cpp 11-qstringview
|
||||
|
||||
First, \c arg(i) replaces \c %1. Then \c arg(total) replaces \c
|
||||
%2. Finally, \c arg(fileName) replaces \c %3.
|
||||
|
||||
One advantage of using arg() over asprintf() is that the order of the
|
||||
numbered place markers can change, if the application's strings are
|
||||
translated into other languages, but each arg() will still replace
|
||||
the lowest-numbered unreplaced place-marker, no matter where it
|
||||
appears. Also, if place-marker \c %i appears more than once in the
|
||||
string, arg() replaces all of them.
|
||||
|
||||
If there is no unreplaced place-marker remaining, a warning message
|
||||
is printed and the result is undefined. Place-marker numbers must be
|
||||
in the range 1 to 99.
|
||||
*/
|
||||
QString QString::arg(QStringView a, int fieldWidth, QChar fillChar) const
|
||||
{
|
||||
ArgEscapeData d = findArgEscapes(*this);
|
||||
|
||||
if (d.occurrences == 0) {
|
||||
qWarning("QString::arg: Argument missing: %s, %s", toLocal8Bit().data(),
|
||||
a.toLocal8Bit().data());
|
||||
if (Q_UNLIKELY(d.occurrences == 0)) {
|
||||
qWarning("QString::arg: Argument missing: %ls, %ls", qUtf16Printable(*this),
|
||||
qUtf16Printable(a.toString()));
|
||||
return *this;
|
||||
}
|
||||
return replaceArgEscapes(*this, d, fieldWidth, a, a, fillChar);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 5.10
|
||||
|
||||
Returns a copy of this string with the lowest-numbered place-marker
|
||||
replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99.
|
||||
|
||||
\a fieldWidth specifies the minimum amount of space that \a a
|
||||
shall occupy. If \a a requires less space than \a fieldWidth, it
|
||||
is padded to \a fieldWidth with character \a fillChar. A positive
|
||||
\a fieldWidth produces right-aligned text. A negative \a fieldWidth
|
||||
produces left-aligned text.
|
||||
|
||||
One advantage of using arg() over asprintf() is that the order of the
|
||||
numbered place markers can change, if the application's strings are
|
||||
translated into other languages, but each arg() will still replace
|
||||
the lowest-numbered unreplaced place-marker, no matter where it
|
||||
appears. Also, if place-marker \c %i appears more than once in the
|
||||
string, arg() replaces all of them.
|
||||
|
||||
If there is no unreplaced place-marker remaining, a warning message
|
||||
is printed and the result is undefined. Place-marker numbers must be
|
||||
in the range 1 to 99.
|
||||
*/
|
||||
QString QString::arg(QLatin1String a, int fieldWidth, QChar fillChar) const
|
||||
{
|
||||
QVarLengthArray<ushort> utf16(a.size());
|
||||
qt_from_latin1(utf16.data(), a.data(), a.size());
|
||||
return arg(QStringView(utf16.data(), utf16.size()), fieldWidth, fillChar);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString QString::arg(const QString& a1, const QString& a2) const
|
||||
\overload arg()
|
||||
|
@ -319,8 +319,14 @@ public:
|
||||
QChar fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
|
||||
QString arg(QChar a, int fieldWidth = 0,
|
||||
QChar fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
QString arg(const QString &a, int fieldWidth = 0,
|
||||
QChar fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
|
||||
#endif
|
||||
QString arg(QStringView a, int fieldWidth = 0,
|
||||
QChar fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
|
||||
QString arg(QLatin1String a, int fieldWidth = 0,
|
||||
QChar fillChar = QLatin1Char(' ')) const Q_REQUIRED_RESULT;
|
||||
QString arg(const QString &a1, const QString &a2) const Q_REQUIRED_RESULT;
|
||||
QString arg(const QString &a1, const QString &a2, const QString &a3) const Q_REQUIRED_RESULT;
|
||||
QString arg(const QString &a1, const QString &a2, const QString &a3,
|
||||
|
@ -1558,7 +1558,7 @@ QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(const QStringRef &prefix)
|
||||
|
||||
#if 1
|
||||
if (namespaceProcessing && !prefix.isEmpty())
|
||||
raiseWellFormedError(QXmlStream::tr("Namespace prefix '%1' not declared").arg(prefix.toString()));
|
||||
raiseWellFormedError(QXmlStream::tr("Namespace prefix '%1' not declared").arg(prefix));
|
||||
#endif
|
||||
|
||||
return QStringRef();
|
||||
@ -1636,7 +1636,7 @@ void QXmlStreamReaderPrivate::resolveTag()
|
||||
if (attributes[j].name() == attribute.name()
|
||||
&& attributes[j].namespaceUri() == attribute.namespaceUri()
|
||||
&& (namespaceProcessing || attributes[j].qualifiedName() == attribute.qualifiedName()))
|
||||
raiseWellFormedError(QXmlStream::tr("Attribute '%1' redefined.").arg(attribute.qualifiedName().toString()));
|
||||
raiseWellFormedError(QXmlStream::tr("Attribute '%1' redefined.").arg(attribute.qualifiedName()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1804,14 +1804,14 @@ void QXmlStreamReaderPrivate::startDocument()
|
||||
if(hasStandalone)
|
||||
err = QXmlStream::tr("The standalone pseudo attribute must appear after the encoding.");
|
||||
if(!QXmlUtils::isEncName(name))
|
||||
err = QXmlStream::tr("%1 is an invalid encoding name.").arg(name);
|
||||
err = QXmlStream::tr("%1 is an invalid encoding name.").arg(value);
|
||||
else {
|
||||
#ifdef QT_NO_TEXTCODEC
|
||||
readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
|
||||
#else
|
||||
QTextCodec *const newCodec = QTextCodec::codecForName(name.toLatin1());
|
||||
if (!newCodec)
|
||||
err = QXmlStream::tr("Encoding %1 is unsupported").arg(name);
|
||||
err = QXmlStream::tr("Encoding %1 is unsupported").arg(value);
|
||||
else if (newCodec != codec && !lockEncoding) {
|
||||
codec = newCodec;
|
||||
delete decoder;
|
||||
|
@ -4726,8 +4726,8 @@ void tst_QString::arg()
|
||||
QString s14( "%1%2%3" );
|
||||
|
||||
QCOMPARE( s4.arg("foo"), QLatin1String("[foo]") );
|
||||
QCOMPARE( s5.arg("foo"), QLatin1String("[foo]") );
|
||||
QCOMPARE( s6.arg("foo"), QLatin1String("[foo]") );
|
||||
QCOMPARE( s5.arg(QLatin1String("foo")), QLatin1String("[foo]") );
|
||||
QCOMPARE( s6.arg(QStringViewLiteral("foo")), QLatin1String("[foo]") );
|
||||
QCOMPARE( s7.arg("foo"), QLatin1String("[foo]") );
|
||||
QCOMPARE( s8.arg("foo"), QLatin1String("[foo %1]") );
|
||||
QCOMPARE( s8.arg("foo").arg("bar"), QLatin1String("[foo bar]") );
|
||||
@ -4788,11 +4788,11 @@ void tst_QString::arg()
|
||||
QCOMPARE( QString("%%%1%%%2").arg("foo").arg("bar"), QLatin1String("%%foo%%bar") );
|
||||
|
||||
QCOMPARE( QString("%1").arg("hello", -10), QLatin1String("hello ") );
|
||||
QCOMPARE( QString("%1").arg("hello", -5), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg("hello", -2), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg(QLatin1String("hello"), -5), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg(QStringViewLiteral("hello"), -2), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg("hello", 0), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg("hello", 2), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg("hello", 5), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg(QLatin1String("hello"), 2), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg(QStringViewLiteral("hello"), 5), QLatin1String("hello") );
|
||||
QCOMPARE( QString("%1").arg("hello", 10), QLatin1String(" hello") );
|
||||
QCOMPARE( QString("%1%1").arg("hello"), QLatin1String("hellohello") );
|
||||
QCOMPARE( QString("%2%1").arg("hello"), QLatin1String("%2hello") );
|
||||
|
Loading…
Reference in New Issue
Block a user