Commit Graph

26 Commits (62de01bf178a2ce629cf64cc73edcd2d88d8eeba)

Author SHA1 Message Date
Thiago Macieira b347d48704 QString/QByteArray: further inline the most common indexOf operations
In the case of QString, the vast majority of searches are case-
sensitive, so by inlining we make the user code call qustrchr() directly
instead of QtPrivate::findString(). In the case of QByteArray, the call
is to memchr(), which being a compiler intrinsic, may itself be inlined
or even just resolved at compile time.

In both cases, a great deal of searches use from=0.

Benchmark for QByteArray; before:
     8.83207052 nsecs per iteration
     22.01568546 CPU cycles per iteration, 2.49 GHz
     60.00000331 instructions per iteration, 2.725 instr/cycle
     21.00000281 branch instructions per iteration, 2.38 G/sec

After:
     6.42561493 nsecs per iteration
     16.01623130 CPU cycles per iteration, 2.49 GHz
     49.00000261 instructions per iteration, 3.059 instr/cycle
     18.00000211 branch instructions per iteration, 2.8 G/sec

This shaves 6 cycles in the execution and 11 instructions (3 of which
were branches), slightly improving the IPC raito, for the QByteArray
case. For QByteArrayView, there are 2 fewer instructions (1 a branch),
but the number of cycles is the same at 16.

Task-number: QTBUG-119750
Change-Id: Ica7a43f6147b49c187ccfffd179e2204ebb6a348
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-12-21 11:13:32 -08:00
Thiago Macieira dfe968e970 QString: inline indexOf() and use a QChar overload
This is a repeat of the last commit, which did the same for QByteArray.
No benchmarks in this commit, assuming the results are similar (at least
for cs = Qt::CaseSensitive).

Task-number: QTBUG-119750
Change-Id: Ica7a43f6147b49c187ccfffd179e1f852272af8b
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2023-12-21 11:13:31 -08:00
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
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
Giuseppe D'Angelo 6f852935e0 QString: fix lifetime issues with QRegularExpression APIs
QString has several functions taking a QRegularExpression: indexOf(),
contains(), and so on. Some of those have an out-argument of type
QRegularExpressionMatch, to report the details of the match (if any).
For instance:

  QRegularExpression re(...);
  QRegularExpressionMatch match;

  if (string.contains(re, &match))
    use(match);

The code used to route the implementation of these functions through
QStringView (which has the very same functions). This however opens
up a lifetime problem with temporary strings:

  if (getString().contains(re, &match))
    use(match); // match is dangling

Here `match` is dangling because it is referencing data into the
destroyed temporary -- nothing is keeping the string alive. This is
against the rules we've decided for Qt, and it's also asymmetric with
the corresponding code that uses QRegularExpression directly instead:

  match = re.match(getString());
  if (match.hasMatch())
    use(match); // not dangling

... although we've documented not to do this. (In light of the decision
we've made w.r.t. temporaries, the documentation is wrong anyways.)
Here QRE takes a copy of the string and stores it in the match object,
thus keeping it alive.

Hence, extend the implementation of the QString functions to keep a
(shallow) copy of the string. To keep the code shared as much as
possible with QStringView, in theory one could have a function taking a
std::variant<QString, QStringView> and that uses the currently active
member. However I've found that std::variant here creates some abysmal
codegen, so instead I went for a simpler approach -- pass a QStringView
and an optional pointer to a QString. Use the latter if it's loaded.

QStringView has some inline code that calls into exported functions, so
I can't change the signature of them without breaking BC; I'm instead
adding new unexported functions and a Qt 7 note to unify them.

Change-Id: I7c65885a84069d0fbb902dcc96ddff543ca84562
Fixes: QTBUG-103940
Pick-to: 6.2 6.3 6.4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-07-10 23:40:24 +02:00
Lucie Gérard 05fc3aef53 Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
2022-05-16 16:37:38 +02:00
Sona Kurazyan 76db8a0b1b Use QLatin1StringView in QString/QLatin1String APIs and docs
- Replaced QLatin1String with QLatin1StringView in QString/QLatin1String
  APIs and docs (except for QLatin1String class declaration and ctor
  names).

- Made the docs look like QLatin1StringView is "The Real Thing".

[ChangeLog][QtCore] Made QLatin1StringView the recommended name for
referring to a Latin-1 string view (instead of QLatin1String).

Task-number: QTBUG-98434
Change-Id: I6d9a85cc956c6da0c910ad7d23be7956e4bd94ac
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2022-03-23 18:06:51 +01:00
Marc Mutz abe3b4c9b9 Extract Header qstringfwd.h
... from qstringalgorithms.h and qutf8stringview.h, in order to
centralize the declaration of the string classes, much like
qcontainerfwd.h does for Qt containers.

[ChangeLog][QtCore] Added header qstringfwd.h containing
forward-declarations of all Qt string classes.

Task-number: QTBUG-98434
Change-Id: I4cf1ede9fe6c286230f4c7e7abe379da28ce5d15
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2022-03-11 20:15:49 +01:00
Sona Kurazyan 82e12c79b2 Add an overload of QStringView::count() for QLatin1String
Required for the API symmetry between QStringView and QLatin1String.

[ChangeLog][QtCore][QStringView] Added an overload of
QStringView::count() for QLatin1String.

Change-Id: Ic49a4b31e8f6f0969eff0f792654d23a60e06c49
Task-numer: QTBUG-98431
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2022-03-09 15:58:47 +01:00
Sona Kurazyan 30d28810ee Add QLatin1String::count(needle)
[ChangeLog][QtCore][QLatin1String] Added QLatin1String::count(needle).

Task-number: QTBUG-98433
Change-Id: I31c9fdf14fd81500722ff9f5998eadf0e6cedc5c
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-03-09 15:58:47 +01:00
Thiago Macieira 8bae441d90 QUtf8StringView: ensure binary compatibility throughout 6.x
We can't depend on whether the user compiles with -std=c++17 or
-std=c++20. So select what we can depend on and make that permanent.

Prior to this change:

 $ cat /tmp/test.cpp
 #include <QtCore/QUtf8StringView>
 void f(QUtf8StringView) {}
 $ qcd include
 $ g++ -S -o - -I. /tmp/test.cpp | grep globl | c++filt
         .globl  f(QBasicUtf8StringView<false>)
 $ g++ -fPIC -std=c++20 -S -o - -I. /tmp/test.cpp | grep globl | c++filt
         .globl  f(QBasicUtf8StringView<true>)

After this change, they're both "false". QUtf8StringView should have
been a concrete class that derived from QBsicUtf8StringView<whichever>
and inherited all its constructors. We'd cause ODR violations in C++20,
but nothing worse than what we usually do for BC reasons.

That solution is too late for Qt 6.x. Let's revisit in 7.0.

Change-Id: I6bcbe88c072a438b8b4efffd166e77199ecb39e3
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit c7deb3400faa1d9389137fe63ffbffade8203850)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2021-04-20 19:33:00 +00:00
Edward Welbourne c9c598d4d7 Mark places where we missed conversion to unicode character types
We should use char32_t for the toUcs4() methods of QString and
QStringView and use char16_t for QString::utf16(), thereby matching
QStringView. These naturally imply knock-on changes in various places.
Unfortunately, we didn't make those changes in Qt 6, so they'll have
to wait for Qt 7.

Change-Id: I18451d4b31b76658092e19d3fcbc8bc0fe5ce307
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2021-01-08 12:40:53 +01:00
Giuseppe D'Angelo ce0b767310 QStringView: add some QRegularExpression-related overloads
[ChangeLog][QtCore][QStringView] Added the indexOf(), contains(),
lastIndexOf() and count() methods taking a QRegularExpression.

Fixes: QTBUG-89050
Change-Id: Ic726754f67e06b3764302d2fad252e0378a77afc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2020-12-10 02:15:18 +01:00
Lars Knoll 8a7b74f6e7 Optimize equality operators for string classes
Using compare() for those operators is not a good idea, as we can't
shortcut comparisons if the string sizes are different. This alone
made our HTML parser in QtGui around 15% slower.

Don't go through QAnyStringView to implement compare() for
QUtf8StringView, use QtPrivate::compareStrings() directly instead.

Task-number: QTBUG-86354
Change-Id: I04869c29c9918161990dc1baf8e943b3a264ff3c
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
2020-10-07 14:57:51 +02:00
Allan Sandfeld Jensen c2be9180b7 Replace Q_REQUIRED_RESULT with [[nodiscard]]
It was already used many places directly making the code inconsistent.

Change-Id: I3b14bc6c333640fb3ba33c71eba97e78c973e44b
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2020-09-25 07:10:45 +02:00
Lars Knoll cb78972e37 Remove deprecated API
And replace it's few remaining usages

Change-Id: I2dfbbaa5259acfece028606bef1e872c5692f9fe
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2020-09-15 08:12:39 +02:00
Marc Mutz 2c9529e158 Long live Q{Any,Utf8}StringView!
We need to add these two classes at the same time, because
QAnyStringView makes all QUtf8StringView relational operators moot. We
might want to add some later, esp. for UTF-8/UTf-8 comparisons, to
avoid the pessimization that we can't early-out on size() mismatch in
QAnyStringView equality operators, but that's an optimization, not a
correctness issue, and can be fixed in a source-compatible way even
after Qt 6 is released.

To deal with the char8_t problem in C++20, make QUtf8StringView a
class template out of which two UTF-8 views can be instantiated: the
Qt 7 version, which depends on C++20 char8_t as value_type, and the Qt
6 version where value_type is a char. Use inline namespaces to map the
QUtf8StringView identifier to one or the other, depending on the C++
version used to compile the user code. The inline namespace names must
needs be a bit ugly, as their inline'ness depends on __cpp_char8_t. If
we simply used q_v1/q_v2 we'd be blocking these names for Qt inline
namespaces forever, because it's likely that inline'ness of other
users of inline namespaces in Qt depends on things other than
__cpp_char8_t. While inline'ness of namespaces is, theoretically
speaking, a compile-time-only property, at least Clang warns about
mixed use of inline on a given namespace, so we need to bite the
bullet here. This is also the reason for the QT_BEGIN_..._NAMESPACE
macros: GCC is ok with the first declaration making a namespace
inline, while Clang warns upon re-opening an inline namespace as a
non-inline one.

[ChangeLog][QtCore][QUtf8StringView] New class.

[ChangeLog][QtCore][QAnyStringView] New class.

Change-Id: Ia7179760fca0e0b67d52f5accb0a62e389b17913
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2020-08-31 22:57:49 +02:00
Allan Sandfeld Jensen 6f0df02d00 Replace Qt CONSTEXPR defines with constexpr
Both normal and relaxed constexpr are required by our new minimum of
C++17.

Change-Id: Ic028b88a2e7a6cb7d5925f3133b9d54859a81744
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
2020-08-14 15:52:58 +02:00
Thiago Macieira 45838673df Implement UTF-16 to UTF-8 case-insensitive compare and make public
Change-Id: Ied637aece2a7427b8a2dfffd16116cf3645c6359
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2020-08-05 21:51:24 -07:00
Jarek Kobus 0475460102 Use QList instead of QVector in corelib
Applied to headers only. Source file to be changed separately.
Omitted statemachine for now to avoid conflicts.
Omitted qmetatype.h for now - to be handled later.

Task-number: QTBUG-84469
Change-Id: I317376037a62467c313467d92955ad0b7473aa97
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
2020-06-25 22:30:59 +02:00
Lars Knoll 03326a2fec Move implementation of QVector/List back to qlist.h
And name the main class QList. That's also the one we document.

This gives less porting pain for our users, and a lot less churn
in our API, as we use QList in Qt 5 in 95% of our API.
In addition, it gives more consistent naming with QStringList and
QByteArrayList and disambiguates QList vs QVector(2|3|4)D.

Fixes: QTBUG-84468
Change-Id: I3cba9d1d3179969d8bf9320b31be2230d021d1a9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2020-06-20 20:01:33 +02:00
Lars Knoll a1056096fc Add support for count() to QStringView
Make the API more symmetric with regards to both QString and QStringRef.

Change-Id: Ia67c53ba708f6c33874d1a127de8e2857ad9b5b8
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2020-05-30 23:11:09 +02:00
Marc Mutz 11dc945403 Port qustrlen and qustrchr to char16_t
Fix callers.

Change-Id: Iaf604c890941aa3de3bd31da300b2066e65968ed
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
2020-05-12 11:49:38 +02:00
Giuseppe D'Angelo a2ddd96ac8 Introduce QString(View)::isValidUtf16
QString(View)s can be built or manipulated in ways that make them
contain/refer to improperly encoded UTF-16 data. Problem is,
we don't have public APIs to check whether a string contains
valid UTF-16. This knowledge is precious if the string is to be fed in
algorithms, regular expressions, etc. that expect validated input
(e.g. QRegularExpression can be faster if it can assume valid UTF-16,
otherwise it has to employ extra checks).

Add a function that does the validation.

[ChangeLog][QtCore][QStringView] Added QStringView::isValidUtf16.

[ChangeLog][QtCore][QString] Added QString::isValidUtf16.

Change-Id: Idd699183f6ec08013046c76c6a5a7c524b6c6fbc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2019-12-20 11:13:22 +01:00
Marc Mutz 353a6946b1 qstringalgorithms.h: add pure, noexcept, constexpr
... where they were missing.

Change-Id: I58c32e57675b5d5ee500722933ef4a356a679e46
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2019-07-29 21:07:17 +03:00
Edward Welbourne a9aa206b7b Move text-related code out of corelib/tools/ to corelib/text/
This includes byte array, string, char, unicode, locale, collation and
regular expressions.

Change-Id: I8b125fa52c8c513eb57a0f1298b91910e5a0d786
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2019-07-10 17:05:30 +02:00