Commit Graph

451 Commits (40da8302e2facc6ff3663321641fdcaa05df1f86)

Author SHA1 Message Date
Anton Kudryavtsev 4fad57e750 QStringView: add isLower and isUpper
[ChangeLog][QtCore][QStringView] Added isLower() and isUpper()

Change-Id: Ie6cd20bd375d42cbdfb17953b2307d025c31ec77
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-11-02 13:50:42 +03:00
Anton Kudryavtsev f331171dd7 QString::fill: port to char16_t
Change-Id: If91ea7b7ceedbf9ed109b064ea5ea5572e7c9b14
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-11-01 23:05:39 +03:00
Anton Kudryavtsev d1f40ea087 QString: remove isSimpleText method
It's legacy method marked as internal.
There are zero occurrences of "isSimpleText"
anywhere in Qt or Qt Creator other than qstring.*

Change-Id: I4961b7b2539fb6552484e77fbea58ba0e6656921
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-26 13:40:51 +03:00
Thiago Macieira 2fefc8c63c QString/QByteArray: add lvalue and rvalue overloads of left/mid/right
The first/last/sliced API may be what we suggest users use, but the vast
majority of the installed codebase uses left/mid/right because they've
been available since time immemorial.

An additional benefit of this is to make left() and right() available as
inline methods.

Change-Id: Ifeb6206a9fa04424964bfffd1788383817ed906c
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-10-25 12:01:58 -07:00
Thiago Macieira f4101f9953 QString/QBA: add lvalue and rvalue overloads to first/last/sliced/chopped
Those ought to have been the original implementation, when they were
added in commit 38096a3d70, for Qt 6.0.

Because these classes are exported, we need to provide the previous only
implementations for MSVC. All other compilers would provide inline or
emit local, out-of-line copies.

Change-Id: Ifeb6206a9fa04424964bfffd178836a2ae56157d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-10-25 12:01:58 -07:00
Thiago Macieira 2fd0996324 QArrayDataPointer: add an allocating constructor
It's by far the most common use, so having to call two things is just
cumbersome.

Change-Id: I79e700614d034281bf55fffd178f454c4e31929e
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-10-25 12:01:58 -07:00
Øystein Heskestad fd48ce0b73 Add support for containers > 4 Gi elements in QDataStream
The format is changed from 6.7 to support more than UINT32_MAX - 1
elements. The format used to have a quint32 size. Now if the size is
larger or equal to 0xfffffffe (2^32 -2) the old size is an extend
value 0xfffffffe followed by one quint64 with the actual value. The
32 bit size with all bits set is still used as null value.

Fixes: QTBUG-105034
Change-Id: I62188be170fe779022ad58ab84a54b1eaf46e5d9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-23 15:10:28 +02:00
Anton Kudryavtsev b419b5b65a QString: port replace_helpers to QSpan
to simplify code

Change-Id: I597432b16d36c6f1d9948d83c9e7270bc7ac160e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-20 18:46:28 +03:00
Anton Kudryavtsev 5452972755 QString::remove: use std::move more
Change-Id: I140a55d79661f013d07ab1805b49026e252d01c8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2023-10-19 09:23:37 +00:00
Anton Kudryavtsev e9e076df55 QString: use qsizetype more
It's last legacy int

Pick-to: 6.6 6.5 6.2
Change-Id: I691f7b15dead91166831cdf6c33a9f4d2d58b62e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-05 22:08:44 +03:00
Anton Kudryavtsev 05737f831c QString::insert: micro optimization
Don't call resize on QVLA, just wrap pointers in QSV
As drive-by, fix typo in comment

Change-Id: Id90236cfb53d861b8bd57fa9452aba4b8d9b20bf
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-05 22:08:44 +03:00
Anton Kudryavtsev c24572d2a4 QString: proper compare of iterators
Canonical way is compare result of std::find_if against end by != operator, not <

Change-Id: Ifffbaf11416ea0738a1ccbb2f2f8482193390070
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-10-04 22:04:46 +03:00
Anton Kudryavtsev 8419b56097 qFindChar: pass char16_t by value
Cheaply-copied types should be passed by value
according to https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-in

Change-Id: I341193c0a65931c1406fc7d711ef74d763178dee
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-03 08:38:02 +03:00
Anton Kudryavtsev ab651c22ae QString::section: replace QList with QVLA
to reduce allocations

Change-Id: Ib996549a018b457d2ee4f073efb0d950268c7738
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-10-02 22:12:35 +03:00
Dennis Oberst 016addc201 QString: assign() [4/4]: (it,it) overload for UTF-8 data types
Implement the missing overload to handle UTF-8 specific data types,
including char8_t (C++20), char, uchar and signed char.

Introduce the helper function 'assign_helper_char8' which handles the
non-contiguous_iterator case. The contiguous_iterator case is already
handled by the QAnyStringView overload.

Include 'qstringconverter.h' at the end of the file, since it can't
be included at the top due to diamond dependency conflicts.
QStringDecoder is an implementation detail we don't want users to
depend on when using assign(it, it). It would be unnatural to not
be able to use a function just because we didn't include an
apparently unrelated header.

[ChangeLog][QtCore][QString] Enabled assign() for UTF-8 data types.

Fixes: QTBUG-114208
Change-Id: Ia39bbb70ca105a6bbf1a131b2533f29a919ff66d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-09-28 17:58:41 +00:00
Anton Kudryavtsev 0ed8db7800 QString::toHtmlEscaped: avoid unconditional copy
Let's find replaceable chars and then do copy

Change-Id: I2d365626218b0daf2023144dee7e901e8e99adc6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2023-09-18 10:14:22 +03:00
Anton Kudryavtsev bd5d313197 QString::replace: replace QList with QVLA
to reduce allocations

Change-Id: Iacc34e3a8825ca6425e8716f2b5e7b5dde2a5df7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-09-18 10:14:16 +03:00
Anton Kudryavtsev 48a44cdf65 QString: use first and last more
It's safe here, precondition is earlier

Change-Id: Ib2192fc729cd012d0983843678c546283a655bfd
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2023-09-18 10:13:59 +03:00
Dennis Oberst b134718c11 QString: use new assign() in operator=({QByteArray, QChar, char *})
operator=(~) and assign() share similar names but, until now, have not
shared the same functionality. This patch introduces the usage of
QString::assign() within the non-sharing assignment operators to
effectively boost efficiency by reusing the available capacity.

Since we're re-using the capacity we update the test case in places
where they don't hold true anymore.

Since these assignment operators are frequently used in many places,
both within Qt and non-Qt code, this patch comes with benchmarks.

The preview of the benchmark results are compared with this patch and
before this patch. The results show a boost in performance for the
QByteArray and 'const char*' overload. The QLatin1StringView overload
already preserved the capacity and has a better performance than the
assign() alternative, so don't us it there.

(x86_64-little_endian-lp64 shared (dynamic) release build (O3); by
gcc 13.2.1, endeavouros ; 13th Gen Intel(R) Core(TM) i9-13900K

benchmarks executed with -perf -iterations 1000000

  * The last value at the EOL represent the string size.

QString &operator=(const QByteArray &a) (current)
  64.3  cycles/iter; 300  instructions/iter; 17   nsec/iter (5)
  65.8  cycles/iter; 366  instructions/iter; 12   nsec/iter (10)
  62.9  cycles/iter; 301  instructions/iter; 11.5 nsec/iter (20)
  61.3  cycles/iter; 315  instructions/iter; 11.1 nsec/iter (50)
  71.4  cycles/iter; 386  instructions/iter; 13   nsec/iter (100)
  136.9 cycles/iter; 811  instructions/iter; 24.5 nsec/iter (500)
  245.8 cycles/iter; 1394 instructions/iter; 42.5 nsec/iter (1'000)

QString &operator=(const QByteArray &a) (before)
  78   cycles/iter; 399  instructions/iter; 15.3 nsec/iter (5)
  82.3 cycles/iter; 465  instructions/iter; 15   nsec/iter (10)
  76.7 cycles/iter; 400  instructions/iter; 14   nsec/iter (20)
  79.5 cycles/iter; 414  instructions/iter; 14.5 nsec/iter (50)
  91.4 cycles/iter; 485  instructions/iter; 16.7 nsec/iter (100)
  189  cycles/iter; 910  instructions/iter; 34.4 nsec/iter (500)
  320  cycles/iter; 1666 instructions/iter; 56   nsec/iter (1'000)

QString &operator=(const char *ch) (current)
  70  cycles/iter; 317  instructions/iter; 12   nsec/iter (5)
  71  cycles/iter; 383  instructions/iter; 12.3 nsec/iter (10)
  64  cycles/iter; 318  instructions/iter; 11.1 nsec/iter (20)
  69  cycles/iter; 340  instructions/iter; 12   nsec/iter (50)
  77  cycles/iter; 419  instructions/iter; 13.5 nsec/iter (100)
  141 cycles/iter; 899  instructions/iter; 24.4 nsec/iter (500)
  280 cycles/iter; 1518 instructions/iter; 48.4 nsec/iter (1'000)

QString &operator=(const char *ch) (before)
  86.7  cycles/iter; 416  instructions/iter; 15   nsec/iter (5)
  87.8  cycles/iter; 482  instructions/iter; 15.7 nsec/iter (10)
  82.4  cycles/iter; 417  instructions/iter; 14.3 nsec/iter (20)
  90.2  cycles/iter; 443  instructions/iter; 15.6 nsec/iter (50)
  101.4 cycles/iter; 518  instructions/iter; 17.7 nsec/iter (100)
  204.4 cycles/iter; 994  instructions/iter; 36.5 nsec/iter (500)
  337.9 cycles/iter; 1789 instructions/iter; 58.9 nsec/iter (1'000)

 * current implemented as: assign(other)
QString &operator=(QLatin1StringView other) (current)
  47.4 cycles/iter; 237 instructions/iter; 8.2  nsec/iter (5)
  46.2 cycles/iter; 237 instructions/iter; 7.9  nsec/iter (10)
  46.8 cycles/iter; 255 instructions/iter; 8    nsec/iter (20)
  59   cycles/iter; 273 instructions/iter; 10.2 nsec/iter (50)
  55   cycles/iter; 300 instructions/iter; 9.5  nsec/iter (100)
  94.3 cycles/iter; 525 instructions/iter; 16.3 nsec/iter (500)
  166  cycles/iter; 804 instructions/iter; 28.7 nsec/iter (1'000)

QString &operator=(QLatin1StringView other) (before)
  14  cycles/iter; 79  instructions/iter; 2.5  nsec/iter (5)
  14  cycles/iter; 79  instructions/iter; 2.6  nsec/iter (10)
  16  cycles/iter; 97  instructions/iter; 3    nsec/iter (20)
  19  cycles/iter; 115 instructions/iter; 3.5  nsec/iter (50)
  23  cycles/iter; 142 instructions/iter; 4.2  nsec/iter (100)
  91  cycles/iter; 367 instructions/iter; 16.6 nsec/iter (500)
  131 cycles/iter; 646 instructions/iter; 23.4 nsec/iter (1'000)

Task-number: QTBUG-106201
Change-Id: Ie852f6abd1cf16164802acddb048eae5df59758f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-09-05 20:58:47 +02:00
Thiago Macieira 9c70e11711 QString: use qustrlen() in the QChar* constructor
Instead of a manual loop, which was there since at least Qt 4.5.1
(beginning of the public history).

Pick-to: 6.5 6.6
Change-Id: Ifa1111900d6945ea8e05fffd177dd3dfea450a67
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2023-08-29 07:39:03 -07:00
Mårten Nordheim 4660a230d5 QString/QByteArray: fix append() wrt. raw data
When appending to an empty string or byte array, we optimize and
copy the internal pointer. But if the other string/byte array was
created with fromRawData this might be temporary data on the stack/heap
and might be de-allocated or overwritten before the string/byte array
is used or is forced to make a deep-copy. This would lead to incorrect
data being used.

This is easy to overlook if you plan to append multiple strings
together, potentially supplied through an argument. Upon appending a
second string it would make a full copy, but there might not be a
guarantee for that. So, it's hard for users to avoid this pitfall!

Fixes: QTBUG-115752
Pick-to: 6.6 6.5 6.2
Change-Id: Ia9aa5f463121c2ce2e0e8eee8a6c8612b7297f2b
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-08-21 23:27:56 +02:00
Thiago Macieira 14d1108d35 Deprecate Q_ASSUME()
We've known for a long time that this is producing worse code with GCC
because of how we implemented in Q_ASSUME_IMPL(). So bite the bullet and
actually deprecate the macro, replacing all extant Q_ASSUME() with
Q_ASSERT().

The replacement is in C++23. Backporting the support onto Q_ASSUME_IMPL
was previously rejected by reviewers.

[ChangeLog][Deprecation Notice] The Q_ASSUME() macro is deprecated. This
macro has different side-effects depending on the compiler used (GCC
compared to Clang and MSVC), and there are certain conditions under
which GCC is known to produce worse code than if the macro was absent.
To give a hint to the compiler for optimizations, use the C++23
[[assume]] attribute.

Change-Id: I80612a7d275c41f1baf0fffd177a3a4ad819fb2d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2023-08-14 17:36:37 -07:00
Thiago Macieira 27a9ce0a16 QString: mark qustrchr() and qustrlen() Q_NEVER_INLINE
Those are "public-ish" and exported functions (qstringalgorithms.h), so
one wouldn't expect that they get inlined most of the time. But they can
be inlined by other code inside qstring.cpp and if QtCore is compiled
with LTO.

More importantly, we want the compiler to inline qustrXXX_avx2() into
it, instead of tail-calling into qustrXXX_avx2(). This may seem like a
no-op but has one very important difference: backtraces will point to an
exported, function instead of an internal symbol. This will then allow
us to create valgrind suppressions.

Before unstripped:
==12492== Invalid read of size 32
==12492==    at 0x53142EE: qustrchr_avx2(QStringView, char16_t) [clone .lto_priv.0] (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==12492==    by 0x54A7AE6: QString::indexOf(QChar, long long, Qt::CaseSensitivity) const [clone .constprop.0] (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==12492==    by 0x5218EC4: treatAsAbsolute(QString const&) (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==12492==    by 0x5218FBA: QDir::filePath(QString const&) const (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)

Before, stripped:
==19477== Invalid read of size 32
==19477==    at 0x5314395: ??? (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19477==    by 0x54A7AE6: ??? (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19477==    by 0x5218EC4: ??? (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19477==    by 0x5218FBA: QDir::filePath(QString const&) const (in /home/tjmaciei/obj/qt/installed/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)

After:
==19692== Invalid read of size 32
==19692==    at 0x53143C5: QtPrivate::qustrchr(QStringView, char16_t) (in /home/tjmaciei/obj/qt/qt6-release/qtbase/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19692==    by 0x54ABA46: ??? (in /home/tjmaciei/obj/qt/qt6-release/qtbase/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19692==    by 0x5218824: ??? (in /home/tjmaciei/obj/qt/qt6-release/qtbase/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19692==    by 0x521891A: QDir::filePath(QString const&) const (in /home/tjmaciei/obj/qt/qt6-release/qtbase/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19692==  Address 0x741919e is 2 bytes before a block of size 32 alloc'd
==19692==    at 0x4843794: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==19692==    by 0x54A8A84: ??? (in /home/tjmaciei/obj/qt/qt6-release/qtbase/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)
==19692==    by 0x531EB1C: QString::fromLatin1(QByteArrayView) (in /home/tjmaciei/obj/qt/qt6-release/qtbase/lib64/glibc-hwcaps/x86-64-v3/libQt6Core.t.so.6.7.0)

Recommended suppressions:
{
   qustrchr_avx2
   Memcheck:Addr32
   fun:_ZN9QtPrivate8qustrchrE11QStringViewDs
}
{
   qustrchr_avx2-with-debuginfo
   Memcheck:Addr32
   fun:UnknownInlinedFun
   fun:UnknownInlinedFun
   fun:_ZN9QtPrivate8qustrchrE11QStringViewDs
}

Change-Id: Ib84fc618ac204205bf7afffd1772b1d87343dfd0
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2023-08-08 10:44:56 -07:00
Ahmad Samir 9bc43ba1c6 QLocaleData:: port bytearray/stringTo{U}LongLong to QSimpleParsedNumber
Change-Id: I97fe38d9b676cf92003a7323ebb5f56b9b79abad
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2023-07-22 22:29:31 +02:00
Ahmad Samir 9d4cd4a63e qstringalgorithms: refactor trimmed_helper_positions
Take by const Str&, trimming a container/view of characters means
removing whitespace from the beginning and end, so the two args were
always cbegin() and cend().

Change-Id: Iac0eda59341f1981204d11013d591013eae3c4e0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-07-22 20:48:11 +03:00
Giuseppe D'Angelo 96d67da420 String-like containers: add implicit conversions towards std:: string views
In C++20 std::basic_string_view has gained a range constructor (like
QStringView always had), but that range constructor has been made
explicit. This means we can't just pass a QString(View) to a function
taking a u16string_view. The consensus seems to be that that types that
should implictly convert towards stdlib's string views should do that
via implicit conversion operators. This patch adds them for

* QByteArrayView => std::string_view
* QString(View) => std::u16string_view
* QUtf8StringView => std::string_view or std::u8string_view, depending
  on the storage_type

QLatin1StringView doesn't have a matching std:: view so I'm not enabling
its conversion.

QByteArray poses a challenge, in that it already defines a conversion
towards const char *. (One can disable that conversion with a macro.)
That conversion makes it impossible to support:

  QByteArray ba;
  std::string_view sv1(ba);  // 1
  std::string_view sv2 = ba; // 2

because:

* if only operator const char *() is defined, then (2) doesn't work
  (situation right now);

* if both conversions to const char * and string_view are defined, then
  (1) is ambiguous on certain compilers (MSVC, QCC). Interestingly
  enough, not on GCC/Clang, but only in C++17 and later modes.

I can't kill the conversion towards const char * (API break, and we use
it *everywhere* in Qt), hence, QByteArray does not get the implicit
conversion, at least not in this patch.

[ChangeLog][QtCore][QByteArrayView] Added an implicit conversion
operator towards std::string_view.

[ChangeLog][QtCore][QString] Added an implicit conversion operator
towards std::u16string_view.

[ChangeLog][QtCore][QStringView] Added an implicit conversion operator
towards std::u16string_view.

[ChangeLog][QtCore][QUtf8StringView] Added an implicit conversion
operator towards std::string_view (QUtf8StringView is using char
as its storage type in Qt 6). Note that QUtf8StringView is planned to
use char8_t in Qt 7, therefore it is expected that the conversion will
change towards std::u8string_view in Qt 7.

Change-Id: I6d3b64d211a386241ae157765cd1b03f531f909a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-07-13 16:19:06 +02:00
Giuseppe D'Angelo 49d177cfba QString docs: miscellanea improvements around string construction
* Correct the semantics of the QString(const char *) constructor
* Mention operator""
* Get rid of QLatin1StringView
* Improve QStringBuilder docs

Change-Id: I80a0833a6d31fae1b05ee49bdb9d2dc6baf84cf0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-07-07 18:19:57 +02:00
Thiago Macieira b1ee49b465 Q{Any,}StringView: optimize lengthHelperContainer for the runtime
Deduplicate it in the process by moving to qstringalgorithms.h.

In non-constexpr contexts, both GCC and Clang were giving up in
pre-calculating the length if the UTF-16 string literal was too big. For
the old code, that was 14 and 16 characters respectively. That number
can be raised by adding some Q_ALWAYS_INLINE and (for GCC's case),
replacing std::char_traits::find() with std::find(). If that limit is
exceeded, we call the newly introduced qustrnlen() function.

qustrnlen() is just qustrchr(), like qstrnlen() is just memchr(). But it
is introduced as a separate function so we could change implementation
if we ever wished to, plus QStringView is only forward-declared at this
point.

Change-Id: Ieab617d69f3b4b54ab30fffd175c560d926db1c3
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-06-11 15:43:02 -07:00
Marc Mutz 05e3880130 QString: add STL-style assign() [3/4]: (it,it) overload for char32_t
This no longer is range-length preserving now, so adapt the
documentation.

For the non-contiguous iterator case, it's actually ok to always
resize(0) and then append(), because, unlike for QList and QVLA, the
resize(0) doesn't actually iterate the container to destroy
elements. It just sets some members and conveniently detach()es for
us.

The char8_t case is even more complicated, since we can, atm, not
include qstringconverter.h into qstring.h, yet qstringconverter is
required for stateful UTF-8 decoding in the input_iterator case. So
that's postponed to yet another patch, and maybe won't make it into
6.6. But I feel it's important to have at least one
non-length-preserving version of assign(it, it) in before release lest
users come to rely on this documented (and de-facto) feature of the
the step-2 assign().

Fixes: QTBUG-106198
Pick-to: 6.6
Change-Id: Id458776e91b16fb2c80196e339cb817adee5d6d9
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2023-06-09 11:50:18 +00:00
Marc Mutz f5ed163c19 QString: add STL-style assign() [2/4]: (it,it) overload for QChar-convertible *it
Restrict the permissible value_types to those QStringView can take,
plus QLatin1Char. All of these implicitly convert to QChar and give
the correct result, even when converted char-by-char.

Task-number: QTBUG-106198
Pick-to: 6.6
Change-Id: Icb44244cb08af391161c4309467d4e0d2d3d3d62
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
2023-06-07 23:18:03 +00:00
Dennis Oberst 54d8d8055e QString: add STL-style assign() [1/4]: non-(it,it) overloads
Implemented assign() methods for QString to align with the
criteria of std::basic_string, addressing the previously missing
functionality. This is a subset of the overloads provided by the
standard.

Reference:
https://en.cppreference.com/w/cpp/string/basic_string/assign

The assign(it, it) overload is a bit more complicated and will be
added in follow-up patches.

[ChangeLog][QtCore][QString] Added assign().

Task-number: QTBUG-106198
Change-Id: Ia1481d184865f46db872cf94c266fef83b962351
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-06-04 06:33:12 +00:00
Edward Welbourne 9da9ca0ac7 Remove unused IS_RAW_DATA() macros from q{string,bytearray}.cpp
They were made redundant at Qt 6, so now they're just defined and undefined.
Don't even do that any more.

Change-Id: Ic4a4a4c39c50c9af417ea6c52be5f69a2d4856c6
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-05-31 16:37:18 +02:00
Thiago Macieira e2a76797e0 QLatin1StringView: un-inline Latin1-UTF8 compare_helper
Commit c630b231ec ("Untangle
QLatin1StringView from qstring.{h,cpp}") moved QLatin1StringView from
qstring.h, causing compilations that included qlatin1stringview.h but
not qstring.h to produce a warning.

By un-inlining, we get an improved comparison functionality without
memory allocation too. So win-win.

 qlatin1stringview.h:325:23: warning: inline function ‘static int QLatin1String::compare_helper(const QLatin1StringView&, const char*)’ used but never defined

This is BC because the actual function that used to be inline continues
to be so, and the old implementation is fine, albeit slower.

Change-Id: Ieab617d69f3b4b54ab30fffd175c4e11d4a3b6dd
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-05-11 21:53:21 -07:00
Marc Mutz 038c1c5978 QString/QByteArray::op>>: don't assume clear() makes the container isNull()
This is something we may want to change at some point, so be explicit
and assign a null container instead of relying on clear().

Add a comment that was present in the QString, but missing in the
QByteArray implementation.

Pick-to: 6.5
Task-number: QTBUG-31283
Task-number: QTBUG-60745
Change-Id: I10d82b8a0c67fff314af526c7b7e0f247c3405fd
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2023-05-04 12:53:23 +02:00
Thiago Macieira cd800da526 QString::insert: replace duplicated code with a recursion
Just call itself after copying the buffer, thus avoiding instantiating
insert_helper() for QVarLengthArray.

The other two cases of QtPrivate::q_points_into_range + QVLA in
qstring.cpp are not worth changing.

Change-Id: I9671dee8ceb64aa9b9cafffd1742fa7bb4cbebd8
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-04-26 07:55:47 +00:00
Ahmad Samir 7191b8fe38 Fix some narrowing conversion warnings
ioctl call for FIONREAD takes an int arg, it won't work correctly
otherwise. Cast the return of the read() call to int, because it won't
read more than buffSize (which is an int).

Change-Id: I130202a732684257bbb0e79c9358b60a61010c46
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-04-08 13:24:04 +02:00
Edward Welbourne db5279825c Corelib: s/Q_OS_MAC/Q_OS_DARWIN/wg except for doc and definition
I got tired of being told off by the inanity 'bot for faithfully
reflecting existing #if-ery in new #if-ery. Retain only the
documentation and definition of the deprecated define.

Change-Id: I47f47b76bd239a360f27ae5afe593dfad8746538
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2023-03-20 19:18:52 +01:00
Ahmad Samir 6e29632006 QString: fix a couple of integral narrowing warnings
Change-Id: Ibc193665c4fe5458a4ba84a3993dcd67a6180048
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-03-12 21:34:43 +02:00
Ahmad Samir 8a1eb24de8 Misc: Fix qsizetype-related narrowing coversions
Task-number: QTBUG-102461
Change-Id: I96757abc50fc45756bc1271a970f819a48021663
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-03-11 12:39:47 +02:00
Tor Arne Vestbø 3b08cbff69 Remove redundant information in QString::toLocal8Bit() docs
Pick-to: 6.5
Change-Id: I794621a599bfab85c6a19300225d0e1ad4948362
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-03-02 12:51:15 +01:00
Tor Arne Vestbø 349bd4db22 Document that to/FromLocal8Bit() does not consider CFStringGetSystemEncoding
The CFStringGetSystemEncoding() defaults to Mac Roman, unless overridden
via ~/.CFUserTextEncoding, which very few users do or even know about.

Make a note in the to/FromLocal8Bit() that we don't consult this function,
or its NSString wrapper, when determining what the local 8 bit encoding is.

Task-number: QTBUG-111443
Change-Id: I89b6040c62d42de0daea9df908d97d9a23e7b160
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2023-03-02 12:51:14 +01:00
Tor Arne Vestbø 3154aec540 doc: Fix spelling of 'equivalent' in QString documentation
Pick-to: 6.5
Change-Id: I1d39bee80fbaf3e3e6eb5e383fd845bb0f9071e5
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2023-03-01 22:22:26 +01:00
Thiago Macieira 09f5bb9969 QString: make insert_helper take the insertee by const-ref
Not all callers pass a view-type object: there are several call points
passing a QVarLengthArray, which means the value ended up being copied.

Introduced in 67108ef8db. Found by
Coverity scan (CID 404702).

Change-Id: I9671dee8ceb64aa9b9cafffd1742f9cda2131752
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2023-02-25 12:31:17 -08:00
Ahmad Samir eb60e94020 QString: don't detach in replace_helper()
I.e. don't detach in the replace() overloads that delegate to
replace_helper() if this string is shared, instead create a new string
and copy characters from this string to it, along with the "after"
string, then swap it with this.

Do the same thing if "before" is shorter than "after" and there isn't
enough capacity to do the replacement without reallocating.

Use std::copy* and std::move*, which will both fallback to
memmove/memcpy, but they have C++ API, which is more readable.

[ChangeLog][QtCore][QString] Using replace() on a currently shared
QString is now done more efficiently

Task-number: QTBUG-106184
Change-Id: If74ffa1ed47636dc23d543d6dc123d8f2b21d537
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-09 22:52:01 +02:00
Ahmad Samir 3a3b76e040 QString: don't detach in insert(qsizetype, QUtf8StringView)
If the string is shared, instead of detaching (which would copy the
whole string data before doing the insertion), create a new string and
copy characters to it as needed then swap it with "this".

[ChangeLog][QtCore][QString] Inserting Utf8 data (e.g. a
QUtf8StringView) into a currently shared QString is now done more
efficiently.

Task-number: QTBUG-106186
Change-Id: I832bde1494108685cc2f630750dfe9b38cd96931
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-09 16:50:02 +02:00
Ahmad Samir 5f73f48556 QString: optimize insert(qsizetype, QUtf8StringView)
Utf8 data is variable-width, ideally we want to write characters at most
once, so insert directly into the QString buffer if inserting at the end
(by delegating to append(QUtf8SV)), and use an intermediate buffer to
hold the converted data before inserting anywhere else.

Task-number: QTBUG-108546
Change-Id: Iabfaeecaf34a1ba11946bd67951e69a45d954d6d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-09 16:49:54 +02:00
Ahmad Samir cc6324665e QString: don't detach in insert()
Instead of detaching when the string is shared, or if the the insertion
would cause a reallocation, create a new string and copy characters to
it as needed, then swap it with "this" string. This is more efficient
than detaching which would copy the whole string before inserting, as
some characters would be copied multiple times.

Use detachAndGrow(), otherwise QStringBuilder unitests fail:
PASS   : tst_QStringBuilder1::initTestCase()
FAIL!  : tst_QStringBuilder1::scenario() 'prepends < max_prepends' returned FALSE. ()
   Loc: [tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp(61)]
PASS   : tst_QStringBuilder1::cleanupTestCase()

The issue is that now when inserting, if the string is going to
reallocated, we create a new string, so the freeSpaceAtBegin()
optimization doesn't work the same way.

void checkItWorksWithFreeSpaceAtBegin(const String &chunk, const Separator &separator)
{
    // GIVEN: a String with freeSpaceAtBegin() and less than chunk.size() freeSpaceAtEnd()
    String str;

    int prepends = 0;
    const int max_prepends = 10;
    while (str.data_ptr().freeSpaceAtBegin() < chunk.size() && prepends++ < max_prepends)
        str.prepend(chunk);
    QVERIFY(prepends < max_prepends);
    ...
    ...

each str.prepend() would have reallocated.

[ChangeLog][QtCore][QString] Calling insert() on a currently shared
string is now done more efficiently.

Task-number: QTBUG-106186
Change-Id: I07ce8d6bde50919fdc587433e624ace9cee05be8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-09 16:49:26 +02:00
Ahmad Samir 67108ef8db QString: split some code from insert() overloads to a static helper
A side-effect of this change is that now almost all insert() overloads
will have the prepend-optimization as the QADP grows at the beginning if
inserting at index 0.

Change-Id: I49c0471ddb02cbbe61a13977650f0993e80040fa
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-09 16:49:15 +02:00
Ahmad Samir 4d7dfd29d1 QString: refactor two insert overloads
Namely insert(qsizetype i, QLatin1StringView) and insert(qsizetype,
const QChar *, qsizetype).

Instead of using d->insert(), tell d.detachAndGrow() to grow at the
beginning if inserting at index 0.

The next commit will split the common code between these two overloads
to a static helper. (Done in multiple steps to make it easier for me to
see what is being changed, and easier to git bisect if needed ...etc).

Change-Id: Idf939df10cca49cb13b66a36b3cf155561630959
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-09 16:49:05 +02:00
Ahmad Samir 498f345228 QtMiscUtils: add some more character helpers
isHexDigit, isOctalDigit, isAsciiDigit, isAsciiLower, isAsciiUpper,
isAsciiLetterOrNumber.

This de-duplicates some code through out.

Rename two local lambdas that were called "isAsciiLetterOrNumber" to not
conflict with the method in QtMiscUtils.

Change-Id: I5b631f95b9f109136d19515f7e20b8e2fbca3d43
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-02-07 20:04:11 +02:00
Thiago Macieira b22ae069ac QRegularExpression: fix count() when the RE matches a surrogate
When the match finds a surrogate pair as the first true Unicode character,
then we need to skip both code units of the pair in order to restart the
search. PCRE2 does not allow us to search for individual UTF-16 code
units.

That actually means that counting "." gives us the count of Unicode
characters.

Fixes: QTBUG-110586
Pick-to: 5.15 6.2 6.4 6.5
Change-Id: I194d0a32c94148f398e6fffd173d5b5be8137e19
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-01-31 19:38:01 -08:00
Ahmad Samir 5353afd7a8 QString: use QtPrivate::qustrchr
Change-Id: I3053da3381fbdd22243683f37dd9f55e58c621dc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 23:56:13 +02:00
Ahmad Samir d4fccc95be QString: change replace_helper() to take a QStringView
Change-Id: Ib3fd5bda96f36bf42da1e5c7230b37fc048c02a4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 23:56:13 +02:00
Ahmad Samir 3575d2d028 QString: remove a try/catch from replace_helper()
I think it was there because of of the QChar array allocated on the
heap (to store a copy of the "after" string when it's part of 'this'
string) and the subsequent ::free() call; instead split some code to a
static helper, and store the copy in a QVarLengthArray; the latter has
SSO, so it'll only heap-allocate if needed, and will take care of
deleting the data.

Remove now unused textCopy() method.

Change-Id: Iaf29d19ebd40d24948f0859d80f45e4c16e5bbce
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-01-31 20:02:54 +02:00
Ahmad Samir 9532339788 QString: use QVLA instead of built-in array
This simplifies the code as a QVLA's size isn't limited to 1024.
Also it allows the code to allocate a big enough buffer to hold the
result, i.e. no reallocations.

insert_helper() takes care of storing a copy of "after" if it points
into "this" string; and "before" pointing into "this" isn't an issue
since we collected the indices before starting the replacement.

Change-Id: I612948187226439349118e65e9525ded2b387da0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-01-31 20:02:54 +02:00
Ahmad Samir 6b89883f6a QString: name args in replace() overloads consistently
Change-Id: I169ecbc4ceaa6eded236fc7421a9eb2e782c6b9a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 20:02:54 +02:00
Ahmad Samir 51aa1c9436 QString: use QtPrivate::q_points_into_range
And remove the static helper pointsIntoRange().

Change-Id: Ie34b232d5cafdd92d46fe6c63ab32da4c68631d9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 20:02:54 +02:00
Friedemann Kleint dc678299c8 QtCore: Fix some macro clashes
The macro decode() in qurlquery.cpp clashes with the static helper
function decode() in qurlrecode.cpp. The macro encode() in
qurlquery.cpp clashes with QStringEncoder::encode().

Macro CBOR_ENCODER_WRITER_CONTROL is defined with various values
in 3rdparty/tinycbor and qcborstreamwriter.cpp.

Pick-to: 6.5
Task-number: QTBUG-109394
Change-Id: I8fdf696863e5b1e6fb0c5607b2dd5b46427b9104
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 18:42:15 +01:00
Ahmad Samir f360aa8bbf QString: move more code to append_helper
This simplifies the append overloads.

Change-Id: I76b56cb24fdd73018fdffd0ea288024a455bfc4b
Reviewed-by: Mate Barany <mate.barany@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 03:18:20 +02:00
Ahmad Samir 04ac810ed0 QString: remove private replace_helper() member function
It was private method, only used internally; replaced by a static
helper, which allows changing its signature more freely without
worrying about BC.

We can pass it "this" by reference and the d-pointer via data_ptr().

It can be removed now without breaking BC because we can[1]:
Remove private non-virtual functions if they are not called by any
inline functions (and have never been).

[1] https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C++#The_Do.27s_and_Don.27ts

Change-Id: I7c4db42ae332af528e65ffd272f1149b92c01fba
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-31 03:18:20 +02:00
Ahmad Samir 26f8ea1224 QString: don't detach in replace(QChar, QChar, case)
If the string is shared, instead of detaching, create a new string and
copy the characters from this string, replacing the ones matching "before"
with "after", to the new string.

Change-Id: I2c33690230d40f3121e60e242666460559258b7b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-30 23:52:42 +02:00
Ahmad Samir 817151c70d QString: use a docs snippets for fromStd*String() methods
Change-Id: Ia9c0c965725aa76c5be6353fe0d1d44674a4d4be
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
2023-01-30 15:27:11 +02:00
Marc Mutz 01ef951c65 QString: port toUcs4_helper() to char16_t/char32_t
This gets rid of 50% of the casts required to call the function, and
removes the last QtCore QStringView(ushort*) user.

As a drive-by, replace an (allowed, but) fishy &str[0] with
str.data(), the mutable overload of which has been available since
C++17.

Task-number: QTBUG-110403
Change-Id: Iad494025b61c53d991e59cc73198bb014a422a93
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-23 15:51:55 +01:00
Ahmad Samir 5d0b338f4d QString: add note about isNull() vs. isEmpty() to more methods
Namely compare() and operator==().

Change-Id: I7e404f2f1df5b93614f7e266bdbebe909e4e7623
Fixes: QTBUG-54505
Pick-to: 6.5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-18 05:53:19 +02:00
Ahmad Samir f090a4785b QStringConverter: use qt_to_latin1() helper from qstring.cpp
This changes the newly-added QLatin1::convertFromUnicode() overload.

Change-Id: Ie465f052e711d72e51217b74b5b51a89c5d8b9e7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-12 05:05:02 +02:00
Ahmad Samir c630b231ec Untangle QLatin1StringView from qstring.{h,cpp}
Searching in qstring.{h,cpp} is slightly easier (it's already too
long).

From the task:
Having similarly-structured header files for all the view classes would
help rebasing the different view classes onto a common template come Qt
7.

Diff best viewed in terminal with git's diff.colorMoved config set to
default.

Task-number: QTBUG-103509
Change-Id: Ie791760bb5bfa23def98d67c206ae8fd00c5f6e6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-07 04:03:22 +02:00
Ahmad Samir a608744c90 Docs: adjust docs after the QLatin1String to QLatin1StringView rename
Unify wording as "{Latin-1,UTF-16} string viewed by \a str".

Drive-by change: Fix a grammatical error, it's "a US-ASCII", not an
(because it's pronounced by the letter name "U" which is pronounced
like "you", so "a" not "an").

Task-number: QTBUG-108711
Pick-to: 6.5
Change-Id: Iff763f4008341c35317bb3d7a2a228767ff6a648
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
2023-01-05 14:46:38 +02:00
Ahmad Samir 9aaf258211 QStringBuilder: document issues with using "auto" keyword
Cleanup QStringBuilder API docs.

Task-number: QTBUG-104354
Change-Id: I00029c8f4bfdf35869396ac14d7d9ba0da34cdb5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2023-01-01 17:47:04 +02:00
Ahmad Samir 5d76c49e9c Use more documentation snippets for QString and its siblings
Pick-to: 6.5
Change-Id: Ia569806b586923473f68b9fe1d98a3628ba46a58
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
2023-01-01 14:13:50 +02:00
Ahmad Samir bab660d124 QStringConverter: add QLatin1::convert{To,From}Unicode()
With the methods that use helpers from qstring.cpp defined in the
latter.

Change-Id: I11d6b0bfb95efe34e56d33d2ecbfe8f4423a9e6c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-30 16:36:24 +02:00
Øystein Heskestad f46bcad993 Remove superfluous Latin-1 case folding table
Use new case folding functions in the implementation of
QLatin1StringMatcher instead.

Task-number: QTBUG-100236
Change-Id: I853091d11070483ad2128b9de3c776f5ca8e7f45
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-22 20:02:29 +01:00
Ahmad Samir e3ae2a505e QString: add needsReallocate() static helper
Split it out from resize(), will be reused in do_replace_helper().

Change-Id: If779e03196678e1618f0ecc114448fed796b43d8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-13 14:41:29 +02:00
Ahmad Samir 6f2a1430c9 QString: don't use noexcept if the method could allocate memory
Change-Id: I49dbd25a41152995d0843fa54d7b3cb4045f3849
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-13 14:41:29 +02:00
Ahmad Samir 59fb33e095 QString: add convenience method converting latin-1 into a QVLA
Less code duplication, as "convert Latin-1 data to Utf16 and store in a
QVLA" is used in various places.

Change-Id: I861f5b8f988411d400db0440b0f5a56c5365e990
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-10 23:37:20 +02:00
Øystein Heskestad 3fedcd4e4a Add Boyer-Moore Latin-1 string searcher with optional case sensitivity
[ChangeLog][QtCore][QString] Added Boyer-Moore Latin-1 string searcher with optional case sensitivity

Task-number: QTBUG-100236
Change-Id: I200a0dac7c8012add1ee02511dba791d233115e0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-08 17:56:47 +01:00
Thiago Macieira 3465b9fe74 QString: merge and optimize the two overloads of SSE2's ustrncmp()
The algorithm is the same, differing only on how we load data onto
vector registers, so they can be merged, simplifying the code base.

For all strings over 16 characters in length, we loop and then we
perform a final overlapped comparison, if necessary. I've kept the 32-
byte-per-loop solution even for pre-AVX2, because that should pipeline
better. For any strings between 4 and 16 characters, we perform a pair
of maybe-overlapped comparisons, of either 4 characters or of 8, so we
consume the full string. That leaves a tail of at most 3 characters in
scalar code.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c8c15d6d761af2
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-07 09:57:59 -08:00
Axel Spoerl 2f22a6e465 Mark static mm_load8_zero_extend [[maybe_unused]]
static Q_ALWAYS_INLINE __m128i mm_load8_zero_extend(const void *ptr)
is unused when compiled on Android.
This causes a compiler warning and blocks CI, if compiled with -Werror.

This patch marks the method [[maybe_unused]], in order to prevent the
warning.

Change-Id: Ife10c0a84ac34196405ce9c2356351d825751adb
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2022-12-07 10:26:06 +01:00
Marc Mutz 6631444eb1 QString/QByteArray/QList: de-pessimize op+ [2/2]: overload on rvalue LHS
The + operator is left-associative, so a + b + c is (a + b) + c.

Apply the same trick C++20 applied to std::string's op+ and overload
for rvalue left-hand sides. This means that a + b + c is now
equivalent to

  [&] {
      auto tmp = a;
      tmp += b;
      tmp += c;
      return tmp;
  }()

removing a ton of temporary buffers (not objects, because CoW makes it
impossible for the compiler to track the single conceptual object
passing through the chain) when not using QStringBuilder (which isn't
available for QList).

This is BC, because the operators are all inline free functions or at
least inline members of non-exported classes.

Use multi-\fn to document the new operators. No \since is needed, as
this doesn't change the set of supported operations, just makes some
of them faster.

[ChangeLog][QtCore][QList/QString/QByteArray] Chained additions (a + b
+ c) now produce only one temporary buffer for the whole expression
instead of one per addition. Using += or QStringBuilder is still
faster, though.

Change-Id: I87e837d8803e79dc29c9268f73e6df9fcc0b09a3
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-07 07:39:38 +00:00
Thiago Macieira 33e682f9af QString: use memcmp() in ucstrncmp() where it's acceptable
ucstrncmp() exists because memcmp() can't be used to sort UTF-16 code
units in little-endian platforms. But it can be used in big endian
platforms and when sorting isn't necessary.

Change-Id: I0e5f6bec596a4a78bd3bfffd16c908c46cc9af2d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-04 17:56:45 -08:00
Thiago Macieira 339aa99fec QString::toLatin1: do the same as fromLatin1 for sub-16 characters
Perform a pair of overlapped loads & stores, so we can perform the
contracting and inserting of question marks in vector code.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c2f5e479b0f6fa
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-04 17:56:45 -08:00
Thiago Macieira 3ef43ca837 QString::fromLatin1: improve the sub-16-character case
For both the [4, 7] and [8,15] length cases, we can perform the same
technique: perform two overlapped loads, zero-extend, then perform two
overlapped stores. The 8-character case could be done in a single
load/store pair, but is not worth the extra conditionals. And it should
have the exact same performance numbers whether we use non-overlapping
4-character operations or completely-overlapping 8-character ones (I
*think* the full overlap is actually better).

The 4-character operation is new in this commit. That reduces the
non-vectorized, unrolled to at most 3 characters.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c257ada774236a
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-04 17:56:45 -08:00
Thiago Macieira 2b9d4afc95 QString::{to,from}Latin1: add the ability to do overlapping tails
If the string length is larger than the number of characters we can
operate on with a single vector loop, we can transform the tail using a
vector too, just overlapping up to 15 characters with the last iteration
o the loop.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c2dcab115e50f7
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-04 17:56:45 -08:00
Thiago Macieira 3b528670e6 QString::toLatin1/SSE: simplify the code to merge question marks
Just move the test of Checked into the lambda, so we can call it
unconditionally.

Change-Id: I0e5f6bec596a4a78bd3bfffd16c9b84ff4a31bb9
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-04 17:56:45 -08:00
Thiago Macieira 23f1d68b09 QString: improve the SSE2 qustrlen to calculate the length as we go
Instead of updating the pointer that we're reading, update the offset
(which is the length). The number of variables we're operating on is the
same (2), but this simplifies the calculation at the end.

BEFORE                             | AFTER
        tzcntl  %edx, %edx         |         tzcntl  %edx, %eax
        subq    %rdi, %rax         |
        sarq    %rax               |
        shrl    %edx               |         shrq    %rax
        addq    %rdx, %rax         |         leaq    (%rax,%rcx), %rax
        ret                        |         ret

We remove one subtraction and one shift. I don't know why it decided to
use LEA instead of ADD... The shift changed from 32- to 64-bit because
we cleaned up the constant 2 (an int) in the file with sizeof(char16_t)
(a size_t), but that has no effect in performance.

Change-Id: I0e5f6bec596a4a78bd3bfffd16c9650a60289f4c
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-04 17:56:45 -08:00
Thiago Macieira 1acd028b0c QString: move the body of qustrlen's SSE2 implementation
Change-Id: I0e5f6bec596a4a78bd3bfffd16c96189533ad94e
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-04 17:56:45 -08:00
Thiago Macieira 40083f380f QString: extract qustrlen's attribute to a macro
I'll need it for the rest of the algorithms.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c1a2b31ac41c6d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-04 17:56:45 -08:00
Thiago Macieira 9d0c29b882 QString: remove the GCC 7 + ASan warning
GCC 7 is not supported in Qt 6, and I really don't expect
anyone would be using it in 2023 with ASan anyway.

Change-Id: I76216ced393445a4ae2dfffd1729a7b82a8776cc
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-04 17:56:45 -08:00
Thiago Macieira 23555d9ac4 QString: reorganize the SSE2 helper functions
I'm going to need add a couple more, so move the block up.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c1942ca56a395b
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-04 17:56:45 -08:00
Thiago Macieira 0cd105079f QString: replace #if with if constexpr for the x86 ISA extensions
Because it looks like it works in all our compilers and gets us at least
basic syntax checking. This is important for me because I usually
compile with a very high -march= flag (currently, tigerlake) and would
not see any syntax errors I may introduce.

Whenever possible, this uses a return inside the if constexpr and then
has the fallback code simply eliminated, but still fully compiled.

Almost all changes are basic reindentation, except for a few variables
that must be declared above the block in question, plus some shenanigans
with the variables in qt_to_latin1_internal(): we want to avoid emitting
multiple loads for the same constants, so we force the compiler to reuse
the shrunk version of the 256-bit registers.

The non-AVX2 code will receive a few minor face-lifts in the next few
commits. Those don't intend to actually improve performance by much. The
real work will happen in the AVX2 code later. I dropped the -Os code
because I don't have the spare time to test it and maintain it; if
there's interest, we can simply disable the entire set vector
optimization set.

Change-Id: Ib42b3adc93bf4d43bd55fffd16c1128c1a4d4875
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
2022-12-04 17:56:45 -08:00
Mate Barany f192ddad8b QString: overload prepend with QUtf8StringView
Add the missing overload.

[ChangeLog][QtCore][QString] Added prepend(QUtf8StringView)
overload.

Task-number: QTBUG-103302
Change-Id: I3f74e884e514ebc0b15a13b074584d8272a02f41
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-02 16:04:14 +01:00
Mate Barany f046589e14 QString: overload insert with QUtf8StringView
Overloading insert is a bit tricky since the size might change after
the conversion so either the tail has to be moved twice or a temporary
buffer is needed. For now, add an ineffective but simple overload as in
the case of the const char *s overload, and do the performance
optimization in a follow-up task (QTBUG-108546).

[ChangeLog][QtCore][QString] Added insert(QUtf8StringView) overload.

Task-number: QTBUG-103302
Change-Id: If01c216ff626da29abb43eb68d4de82824f3bfba
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-02 16:04:11 +01:00
Mate Barany 2ffdb3bcdd QString: overload the += operator to handle QUtf8StringView
The += operator is already overloaded to handle QStringView and
QLatin1String - add the missing QUtf8StringView overload.

[ChangeLog][QtCore][QString] Added operator+=(QUtf8StringView)
overload.

Task-number: QTBUG-103302
Change-Id: Iec6940bad7866310c826a130b98accebc3c82aa8
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-02 16:04:06 +01:00
Mate Barany d2e1d73bf1 QString: overload append to accept QUtf8StringView
Add the missing overload, among other things it is needed to
implement QTBUG-103302.

[ChangeLog][QtCore][QString] Added append(QUtf8StringView)
overload.

Task-number: QTBUG-103302
Change-Id: I576f73c1919e3a1f1a315d0f82c708e835686eb1
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-12-02 16:04:01 +01:00
Øystein Heskestad b977ae371a Add In-place utf-8 case-insensitive comparisons
Also add optimizations for more string comparisons and add tests and
benchmarks.

[ChangeLog][QtCore][QString] Added utf-8 case-insensitive comparisons

Fixes: QTBUG-100235
Change-Id: I7c0809c6d80c00e9a5d0e8ac3ebb045cf7004a30
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-02 11:35:49 +01:00
Marc Mutz 5d41ec46e9 QString/QByteArray: de-pessimize op+ [1/2]: non-const return types
const return types prevent move semantics, so drop the const.

This is BC, because the operators are all inline free functions. In
particular, they're not exported (MSVC mangles the return type).

[ChangeLog][QtCore][QString/QByteArray] operator+ no longer returns
a const object, enabling move-semantics on the return value, but also
hidden detaches.

Change-Id: Ifc18f6b1df1e3840f57b2521949dbade8e11fd76
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-12-01 08:10:11 +00:00
Ahmad Samir d47061f62f QString: optimize replace() when both before and after have size == 1
By delegating to replace(QChar, QChar, cs).

Change-Id: I50b8f4031df3dd8042ddfcb55640f9edc853dc85
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-11-30 15:48:51 +02:00
Giuseppe D'Angelo 3ccd1d2d83 QStringView::split: doc tidies
QStringView is a borrowed range, so views into it are always valid,
even if the QStringView itself is destroyed. Clarify the comment.
Fix another typo (referring to the view as "string") as well.

Pick-to: 6.2 6.4
Change-Id: I8a4f45494d44d5a47e3c1f764f12c899ad7ee83d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2022-11-30 13:48:51 +00:00
Edward Welbourne 6c435e5dd4 Restore end-of-parse reporting to qstrntod()
Rework QSimpleParsedNumber to store a qsizetype whose sign serves as
ok flag (positive is ok, zero and negative are not) and magnitude is
the number of characters used. This replaces an endptr that was set to
null to indicate !ok, but that deprived us of end-of-parse
information, which is needed for number-parsing. In particular, JS's
parsing of numbers accepts overflow (where qstrntod() flags it as
invalid) as infinity; so qstrntod() does need to say how long the
overflowing (but JS-valid, none the less) number-text was.

Modify all callers of functions using this (recently-introduced) type
and add tests that fail without this fix.

Fixes: QTBUG-108628
Change-Id: I416cd213e1fb8101b1af5a6d43615b970a5db9b4
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-11-24 10:06:53 +01:00
Ahmad Samir d9637d0781 QString: don't detach in removeStringImpl()
- If this string is not shared, modify it directly
- If this string is shared, instead of detaching copy the characters
  from this string, except the ones that are going to be removed, to a
  new string and swap it. This is more efficient than detaching, which
  would copy the whole string including the characters that are going
  to be removed.

This affects:
remove(const QString &str, Qt::CaseSensitivity cs)
remove(QLatin1StringView str, Qt::CaseSensitivity cs)

Adjust the unittests to test both code paths.

[ChangeLog][QtCore][QString] Improved the performance of
QString::remove() by avoiding unnecessary data copying. Now, if this
string is (implicitly) shared with another, instead of copying
everything and then removing what we don't want, the characters from
this string are copied to the destination, except the ones that need to
be removed.

Task-number: QTBUG-106181
Change-Id: Id8eba59a44bab641cc8aa662eb45063faf201183
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-11-17 02:15:28 +00:00
Thiago Macieira 2ea3d2e924 QLocale: make qt_asciiToDouble() do case-insensitive comparisons
To "inf" and "nan".

Change-Id: Ieba79baf5ac34264a988fffd172676e1a776a0b1
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2022-11-16 16:15:32 -08:00