Commit Graph

1877 Commits (da4c0de7fbb01034e162a5ffeb17e7f7fbeed243)

Author SHA1 Message Date
Marc Mutz c70c81b371 Long live QCryptographicHash::hashInto()!
Until now, QCryptographicHash had a big drawback over the underlying
C APIs: at least one extra memory allocation: Either you created a
QCryptographicHash object (allocates a Private), and enjoy noexcept
addData() and resultView(), or you used the static hash() function
(which creates a Private on the stack, so doesn't need to allocate
one), but then we needed to return in an owning container.

Enter QSpan and hashInto(), which allow the user to provide a buffer
into which to write, and therefore can be completely noexcept and
(apart from a missing optimization which, however, doesn't affect the
API) deliver near C-API efficiency.

We don't have QMutableByteArrayView, which would deal with the
different types of equivalent char types for us, so we overload for
QSpan<std::bytes>, QSpan<char> and QSpan<uchar>, which makes the
overload set accept roughly what QByteArrayView would accept, too.

Return by QByteArrayView because that has a richer API than QSpan,
which lacks (on purpose) string-ish API.

[ChangeLog][QtCore][QCryptographicHash] Added hashInto().

Task-number: QTBUG-125431
Change-Id: I80ecc7151d3418a36c4d5db6d22d0b82c869b19f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-05-29 14:24:29 +02:00
Marc Mutz 462c958a92 QSpan: add as_(writable_)bytes
For std::span, these are free functions in namespace std and therefore
work for anything implicitly convertible to std::span,
incl. QSpan. But they're C++20, QSpan needs something for C++17
builds.

By adding them as hidden friends for QSpan, we allow unqualifid calls
to transparently resolve to the respective overload, ensuring
source-compatibility between std:: and QSpan, and, eventually, a
transition back to std::as_*_bytes.

I considered the alternative to add these functions in the q20
namespace, but q20::as_bytes() would have to take QSpan, and QSpan is
convertible from more types than std::span, so we wouldn't be able to
guarantee that std::as_bytes(t) works for all T t for which
q20::as_bytes(t) works, the fundamental guarantee for namespace qNN.

[ChangeLog][QtCore][QSpan] Added std::span-style as_bytes() and
as_writable_bytes() functions.

Fixes: QTBUG-125489
Change-Id: Ia9a7560c7843e182892608178433be7349c825ba
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-23 16:18:35 +02:00
Marc Mutz 6ea123ca4c tst_QSpan: fix a typo
We've already tested fixed-size-0 spans for default-constructibility
two lines before. We need to check dynamically-sized spans here.

This doesn't extend test coverage: in the course of the function we've
already default-constructed the correct type.

Amends f82cf6333e.

Pick-to: 6.7
Change-Id: Ibb192b1661f12babb449752bf107eca404a95ad2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-22 18:18:12 +02:00
Marc Mutz 00099c057c tst_QCryptographicHash: mask a QSKIP in addDataAcceptsNullByteArrayView()
We know NumAlgorithms is not supported, so don't print a skipped
warning, by not including that enumerator in the test data in the
first place.

Amends 96dc4acb23.

Pick-to: 6.7
Change-Id: Ie19f7ebcceb855b9363017c8b2626dae99e23313
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2024-05-19 14:27:01 +02:00
Marc Mutz 8586f9e1b9 QCryptographicHash: add specific test for static hash() function
The test already exercised the function here and there, but it lacked
a central place to test the static hash() method, so add one.

Pick-to: 6.7 6.5
Change-Id: I229bc8a8ed07e0036f60de62ecc4d11ef88dd20e
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-19 14:25:33 +02:00
Marc Mutz 6736fe3a0f tst_QSpan: fix GCC 11 -Wmaybe-uninitialized
GCC 11 doesn't understand that 'i' isn't ever read from (because all
spans created over it have size zero), but initialize it nonetheless
to suppress the warning.

Amends f82cf6333e.

Pick-to: 6.7
Change-Id: Ibfb3e9b7fdcbe93c43b7873986c74b4b5a0c9e54
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2024-05-19 12:24:41 +00:00
Ivan Solovev 3ca9877f8c QSizeF: add qFuzzyCompare and qFuzzyIsNull overloads
[ChangeLog][QtCore][QSizeF] Added qFuzzyCompare and qFuzzyIsNull
overloads for QSizeF

Drop the custom qFuzzyCompare() implementation from
tst_qgraphicsgridlayout.cpp

Task-number: QTBUG-120308
Change-Id: I32d11c1c81d0503914a8168b5e960a8c6ce943d9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-14 14:33:21 +02:00
Tatiana Borisova c2826805de QSize(F): use comparison helper macros
Also explicitly add QSizeF vs QSize comparison. Previously such
comparison was implicitly converting QSize to QSizeF, and doing the
fuzzy comparison. We have to keep the old behavior to avoid
breaking user code, so use fuzzy comparison in the new operators
as well.

As a drive-by: put all the hidden friends in the private section.

Done-with: Ivan Solovev <ivan.solovev@qt.io>
Task-number: QTBUG-120308
Change-Id: Ia52adc97c557e475b19f5c16f9dd8c992637280e
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-14 14:33:21 +02:00
Ivan Solovev a4341827ac QEasingCurve: use comparison helper macros
Like with the QLine(F) case, we have to use QT_CORE_REMOVED_SINCE to
remove the old member operators, but also need to guard the new friend
functions with !(QT_CORE_REMOVED_SINCE), because QEasingCurve is also
one of the core types, and on Windows the metatype interface for it is
instantiated in removed_api.cpp.

Task-number: QTBUG-120308
Change-Id: I1bd66f7230afd3eba868d05fd496ab13a0331178
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-10 16:31:28 +02:00
Ivan Solovev 473d06970d QMarginsF: add qFuzzyCompare and qFuzzyIsNull overloads
[ChangeLog][QtCore][QMarginsF] Added qFuzzyCompare and qFuzzyIsNull
overloads for QMarginsF

Task-number: QTBUG-120308
Change-Id: I7c1ceaa9ba544458738b71bf326395eef59e7a54
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-10 15:33:40 +02:00
Ivan Solovev eb178d3e51 QMargins(F): use comparison helper macros
Also explicitly add QMarginsF vs QMargins comparison. Previously such
comparison was implicitly converting QMargins to QMarginsF, and doing the
fuzzy comparison. We have to keep the old behavior to avoid
breaking user code, so use fuzzy comparison in the new operators
as well.

Task-number: QTBUG-120308
Change-Id: Ic82f64078cd991859b851f24aa7017ef0b91a4e1
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-10 15:33:40 +02:00
Ivan Solovev 8a54d25a46 Fix QMarginsF::operator==() for zero margins
The (in)equality operators for QMarginsF are documented to use fuzzy
comparison. However, the implementation unconditionally used
qFuzzyCompare which is incorrect for the case of 0 margins.
Update the implementation to use a combination of qFuzzyIsNull and
qFuzzyCompare, like it's done for QPointF.

[ChangeLog][QtCore][QMarginsF] Fixed a bug when equality comparison
returned incorrect results if one of the margins was zero.

Task-number: QTBUG-120308
Change-Id: I6e785fe8b523f6aa5f5317fb75877fdbf4e086c2
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-10 15:33:40 +02:00
Ivan Solovev 9d4e1b9f8d QRectF: add qFuzzyCompare and qFuzzyIsNull overloads
[ChangeLog][QtCore][QRectF] Added qFuzzyCompare and qFuzzyIsNull
overloads for QRectF

Task-number: QTBUG-120308
Change-Id: Ie2eee0a28b902bdfeb91be45a164be659aef1a20
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-10 15:33:40 +02:00
Ivan Solovev 30bf163355 QRect(F): use comparison helper macros
Also explicitly add QRectF vs QRect comparison. Previously such
comparison was implicitly converting QRect to QRectF, and doing the
fuzzy comparison.
The new operators are directly calling operator==(QPointF, QPoint),
which also does the fuzzy comparison, so the old behavior is preserved.

As a drive-by: move the operators into the private section.

Task-number: QTBUG-120308
Change-Id: I9b96ed4266e6a6c02a52c8cfff6ec1b2d036a7ca
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-10 15:33:40 +02:00
Ivan Solovev 9bedf8a53c QLineF: add qFuzzyCompare and qFuzzyIsNull overloads
[ChangeLog][QtCore][QLineF] Added qFuzzyCompare and qFuzzyIsNull
overloads for QLineF

Task-number: QTBUG-120308
Change-Id: I3d032f47851d886adce95ac72109fde169892688
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-10 15:33:40 +02:00
Ivan Solovev 7072030d93 Fix QLineF::isNull behavior when handling zero points
QLineF::isNull was using qFuzzyCompare on the x and y components of its
points, which was not working correctly if some of the components was
equal to zero. The correct approach is to use qFuzzyIsNull togeter with
qFuzzyCompare. This approach is already implemented in qFuzzyCompare()
overload for QPointF, so just use it.

Add unit-tests for QLine(F)::isNull.

[ChangeLog][QtCore][QLineF] Fixed a bug when QLineF::isNull() returned
incorrect result if the start or end point contained a zero component.

Change-Id: I3cfe6406b1299de32fe82b1fcbfb0416f0eaac15
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-10 15:33:40 +02:00
Ivan Solovev 2a847dd93b QLine(F): use comparison helper macros
Also explicitly add QLineF vs QLine comparison. Previously such
comparison was implicitly converting QLine to QLineF, and doing the
fuzzy comparison.
The new operators are directly calling operator==(QPointF, QPoint),
which also does the fuzzy comparison, so the old behavior is preserved.

Remove the old relational operators using QT_CORE_REMOVED_SINCE, but
also wrap the new operators in !defined(QT_CORE_REMOVED_SINCE).
That is required, because on Windows the instantiation of
QMetaTypeInterface<QLine(F)> happens in removed_api.cpp (as both
qline.h and qmetatype.h are already included there). If we just add
removed member operators into removed_api.cpp, the metatype interface
will not be able to create an equals() function, because of the
ambiguity in equality operators (member vs friend). That's why we have
to exclude the new friend operators from removed_api.cpp.

Done-with: Fabian Kosmale <fabian.kosmale@qt.io>
Task-number: QTBUG-120308
Change-Id: Ibbf5ec077f69c75da0d36a8be5596acd0fcd44d0
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-10 15:33:39 +02:00
Ivan Solovev fa0d77e290 Add qFuzzyCompare() and qFuzzyIsNull() overloads for QPointF
Use the new qFuzzyCompare() overload in op==(QPointF, QPointF).

[ChangeLog][QtCore][QPointF] Added qFuzzyCompare() and qFuzzyIsNull()
overloads for QPointF.

Task-number: QTBUG-120308
Change-Id: I522164acb65432bf55c58b55575f25535d27e27a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-10 15:33:39 +02:00
Ivan Solovev d999e64692 QPoint(F): use comparison helper macros
Explicitly add QPointF vs QPoint comparison. Previously such
comparison was implicitly converting QPoint to QPointF, and
doing the fuzzy comparison. We have to keep the old behavior to
avoid breaking user code, so explicitly use fuzzy comparison in
the new operators.

As a drive-by: move the friend functions into the private section,
so that they are actually hidden friends.

Task-number: QTBUG-120308
Change-Id: I471a890b8332455e8b2dc1b99e5fba4ada168a30
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
2024-05-10 15:33:39 +02:00
Tatiana Borisova ecb0878cbc QVersionNumber: use new comparison helper macros
Replace public friend operators operator==(), operator!=(),
operator<(), etc of QVersionNumber to friend methods
comparesEqual() / compareThreeWay().

Task-number: QTBUG-120304
Change-Id: Ib94a1a28ca9843ca5d5a8d07f41c63de9fe584bb
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-05-06 22:47:55 +02:00
Jari Helaakoski 30cc8a28de Fix test compilation issues with QtLite configuration
Now developer build tests compile, but some are not working.
Functional fix will come later via separate tasks.

Task-number: QTBUG-122999
Change-Id: I70487b46c1b32ba4279cb02a4978e4f55ac0d310
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-05-06 14:29:02 +00:00
Tatiana Borisova 2606c09666 QBitArray: use new comparison helper macros
Replace public friend operators operator==(), operator!=() of
QBitArray to friend method comparesEqual() and
Q_DECLARE_EQUALITY_COMPARABLE macro.

Task-number: QTBUG-120304
Change-Id: I6b47111c144016b3aa05f01c8035c32d164291ad
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-04-26 20:11:14 +02:00
Volker Hilsheimer 8424a64014 Fix warning: remove unused parameter
Pick-to: 6.7 6.6 6.5
Change-Id: I5794e38e1e9871f14c9a8df6483e57c1922dace2
Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Reviewed-by: Pavel Dubsky <pavel.dubsky@qt.io>
2024-04-04 00:51:46 +00:00
Ahmad Samir 66dd00dcfd QCommandLineParser: remove redundant #ifdef from unittest
C++11 has been required for a long time.

Pick-to: 6.7 6.6 6.5
Change-Id: Ib6c1571b100dd4eb8194d515f2180ca26481b556
Reviewed-by: David Faure <david.faure@kdab.com>
2024-03-16 16:41:03 +02:00
Alexandru Croitor fb69efb9c9 CMake: Make a few more auto tests standalone
Pick-to: 6.7
Change-Id: I80988114bd906447a2ab712d5432a489e095a5c1
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-03-14 01:14:18 +01:00
Ivan Solovev e55ee873e9 QTypeRevision: use comparison helper macros
QTypeRevision consists of two quint8 values: major and minor version.
Each of the versions can be unknown.
The rules for comparing with the unknown version are as follows:

 zero version < unknown version < non-zero version

At the same time, two unknown versions are considered equal.

This makes the comparison a bit tricky, but it still fits into the
category of strong ordering.

Replace the existing friend relational operators with helper functions
and comparison helper macros, making this type strongly ordered.

Update the unit-tests to use the new comparison helper test functions.
As the test functions check the reversed arguments as well, we can
reduce the number of rows for the data-driven comparison test.

Fixes: QTBUG-120359
Change-Id: Ib6f1037fc7b5fed148e35ee48b56b05dcd36b3b4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-13 20:34:22 +01:00
Ivan Solovev 81dcb7c8be QTypeRevision: convert comparison test to data-driven
This patch simplifies the checks when migrating the class to comparison
helper macros.

Task-number: QTBUG-120359
Change-Id: I47a6ba20d3b89c31edc2f432621eae9385fbd0a3
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-13 20:34:22 +01:00
Thiago Macieira 45fd36f148 qHash: make hashing of QLatin1StringView be the same as QString
Everywhere, except for ARM.

Change-Id: I50e2158aeade4256ad1dfffd17b11ca2d57ad1fb
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-12 17:23:11 -08:00
Thiago Macieira 55959aefab qHash: implement an AES hasher for QLatin1StringView
It's the same aeshash() as before, except we're passing a template
parameter to indicate whether to read half and then zero-extend the
data. That is, it will perform a conversion from Latin1 on the fly.

When running in zero-extending mode, the length parameters are actually
doubled (counting the number of UTF-16 code units) and we then divide
again by 2 when advancing.

The implementation should have the following performance
characteristics:
* QLatin1StringView now will be roughly half as fast as Qt 6.7
* QLatin1StringView now will be roughly as fast as QStringView

For the aeshash128() in default builds of QtCore (will use SSE4.1), the
long loop (32 characters or more) is:

      QStringView                             QLatin1StringView
    movdqu -0x20(%rax),%xmm4       |        pmovzxbw -0x10(%rdx),%xmm2
    movdqu -0x10(%rax),%xmm5       |        pmovzxbw -0x8(%rdx),%xmm3
    add    $0x20,%rax              |        add    $0x10,%rdx
    pxor   %xmm4,%xmm0             |        pxor   %xmm2,%xmm0
    pxor   %xmm5,%xmm1             |        pxor   %xmm3,%xmm1
    aesenc %xmm0,%xmm0                      aesenc %xmm0,%xmm0
    aesenc %xmm1,%xmm1                      aesenc %xmm1,%xmm1
    aesenc %xmm0,%xmm0                      aesenc %xmm0,%xmm0
    aesenc %xmm1,%xmm1                      aesenc %xmm1,%xmm1

The number of instructions is identical, but there are actually 2 more
uops per iteration. LLVM-MCA simulation shows this should execute in the
same number of cycles on older CPUs that do not have support for VAES
(see <https://analysis.godbolt.org/z/x95Mrfrf7>).

For the VAES version in aeshash256() and the AVX10 version in
aeshash256_256():

      QStringView                             QLatin1StringView
    vpxor  -0x40(%rax),%ymm1,%ym   |        vpmovzxbw -0x20(%rax),%ymm3
    vpxor  -0x20(%rax),%ymm0,%ym   |        vpmovzxbw -0x10(%rax),%ymm2
    add    $0x40,%rax              |        add    $0x20,%rax
                                   |        vpxor  %ymm3,%ymm0,%ymm0
                                   |        vpxor  %ymm2,%ymm1,%ymm1
    vaesenc %ymm1,%ymm1,%ymm1      <
    vaesenc %ymm0,%ymm0,%ymm0               vaesenc %ymm0,%ymm0,%ymm0
    vaesenc %ymm1,%ymm1,%ymm1               vaesenc %ymm1,%ymm1,%ymm1
    vaesenc %ymm0,%ymm0,%ymm0               vaesenc %ymm0,%ymm0,%ymm0
                                   >        vaesenc %ymm1,%ymm1,%ymm1

In this case, the increase in number of instructions matches the
increase in number of uops. The LLVM-MCA simulation says that the
QLatin1StringView version is faster at 11 cycles/iteration vs 14 cyc/it
(see <https://analysis.godbolt.org/z/1Gv1coz13>), but that can't be
right.

Measured performance of CPU cycles, on an Intel Core i9-7940X (Skylake,
no VAES support), normalized on the QString performance (QByteArray is
used as a stand-in for the performance in Qt 6.7):

                        aeshash              |  siphash
                QByteArray  QL1SV   QString     QByteArray  QString
dictionary      94.5%       79.7%   100.0%      150.5%*     159.8%
paths-small     90.2%       93.2%   100.0%      202.8%      290.3%
uuids           81.8%       100.7%  100.0%      215.2%      350.7%
longstrings     42.5%       100.8%  100.0%      185.7%      353.2%
numbers         95.5%       77.9%   100.0%      155.3%*     164.5%

On an Intel Core i7-1165G7 (Tiger Lake, capable of VAES and AVX512VL):

                        aeshash              |  siphash
                QByteArray  QL1SV   QString     QByteArray  QString
dictionary      90.0%       91.1%   100.0%      103.3%*     157.1%
paths-small     99.4%       104.8%  100.0%      237.5%      358.0%
uuids           88.5%       117.6%  100.0%      274.5%      461.7%
longstrings     57.4%       111.2%  100.0%      503.0%      974.3%
numbers         90.6%       89.7%   100.0%      98.7%*      149.9%

On an Intel 4th Generation Xeon Scalable Platinum (Sapphire Rapids, same
Golden Cove core as Alder Lake):

                        aeshash              |  siphash
                QByteArray  QL1SV   QString     QByteArray  QString
dictionary      89.9%       102.1%  100.0%      158.1%*     172.7%
paths-small     78.0%       89.4%   100.0%      159.4%      258.0%
uuids           109.1%      107.9%  100.0%      279.0%      496.3%
longstrings     52.1%       112.4%  100.0%      564.4%      1078.3%
numbers         85.8%       98.9%   100.0%      152.6%*     190.4%

* dictionary contains very short entries (6 characters)
* paths-small contains strings of varying length, but very few over 32
* uuids-list contains fixed-length strings (38 characters)
* longstrings is the same but 304 characters
* numbers also a lot contains very short strings (1 to 6 chars)

What this shows:
* For short strings, the performance difference is negligible between
  all three
* For longer strings, QLatin1StringView now costs between 7 and 17% more
  than QString on the tested machines instead of up to ~50% less, except on
  the older machine (where I think the main QString hashing is suffering
  from memory bandwidth limitations)
* The AES hash implementation is anywhere from 1.6 to 11x faster than
  Siphash
* Murmurhash (marked with asterisk) is much faster than Siphash, but it
  only managed to beat the AES hash in one test

Change-Id: I664b9f014ffc48cbb49bfffd17b045c1811ac0ed
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-12 18:23:09 -07:00
Thiago Macieira 970aad5418 qHash: implement chunked hashing of QLatin1StringView
So that it hashes to the same value as QString{,View}.

In order to test this, you must either run on a CPU other than ARM and
x86, or disable the AES hasher. I did that and can confirm siphash and
murmurhash do work with on-the-fly conversion from Latin-1.

Change-Id: I664b9f014ffc48cbb49bfffd17b03e5e62ec4e89
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-12 17:23:09 -08:00
Thiago Macieira 9a2e21174a QHash: implement the heterogeneous non-const operator[]
This complements the previous commit by adding the heterogeneous lookup
in operator[]. Unlike the members of the previous commit, this one may
insert into the hash, in which case it needs a way to cast from the
heterogeneous type K to the actual Key type.

Change-Id: I664b9f014ffc48cbb49bfffd17b037c1063dfb91
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-12 17:23:08 -08:00
Thiago Macieira b53c153a10 QHash: add support for heterogeneous key lookups
This implements support in QHash and QMultiHash for lookups of
heterogeneous key types that produce the same hash value. This is
implemented by duplicating each of the following functions into an
overload on Key and one a template that is enable_if-constrained to a
key type that meets the requirement:
 * contains
 * count
 * equals_range
 * find
 * operator[] (const only)
 * remove
 * take
 * value
 * values (QMultiHash)

The non-const operator[] may insert into the hash, so it's not part of
this commit.

Change-Id: I664b9f014ffc48cbb49bfffd17b037852f0fd192
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-03-12 17:23:06 -08:00
Giuseppe D'Angelo 7f7b5ff3a1 QSpan: add construction from initializer_list
P2447 has been merged in C++26, backport the same functionality.

This makes QSpan<const T> a proper replacement for a const QList<T>&
parameter, because now both can be built via a braced-init-list.

  // void f(const QList<int> &l); // old
  void f(QSpan<const int>);       // new

  f({1, 2, 3});                   // now OK

This is, technically speaking, SiC: in the presence of both `f`
overloads, the code above would have called the QList one. Now instead
the call is ambiguous.

We've been there already -- this is QString and QStringView all over
again, and the solution is the same: get rid of the owning container
overload. I'd rather have this construction *sooner* rather than *later*
in order to minimize the fallout.

And just like QString vs QStringView, there's nothing really doable to
prevent instant-dangling situations:

  QStringView v = getString();    // dangles
  QSpan<const int> s = {1, 2, 3}; // ditto

except for using QSpan (QStringView) as a *parameter type only*.

Note that QSpan with dynamic extent was already convertible from
std::initializer_list through its ranged constructor. However this fact
alone doesn't unlock the above syntax. QSpan with a static extent was
also convertible for the same reason. (This is non-standard:
std::span's range constructor for static extents is explicit, but QSpan
doesn't follow that design choice and makes the constructors implicit
instead.)

Found in API-review.

Pick-to: 6.7
Change-Id: I160ab5b292b0c2568cd9a7ad1b4430085f475c29
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2024-03-06 08:44:46 +00:00
Giuseppe D'Angelo 73bf1c1a9b QList: add uninitialized resizes
Creating a QList of a given size, or resizing it to a given size, will
always value-initialize its elements. This commit adds support for
uninitialized construction and resizes. The intended use case is using a
QList as storage-to-be-overwritten:

  QList<int> list(size, Qt::Uninitialized);

  fillWithData(list.data(), list.size);

How do we define "uninitialized":

1) if T is constructible using Qt::Uninitialized, use that;
2) otherwise, default-construct T.

In detail:

1) covers (Qt-ish) datatypes that have a default constructor that
   initializes them, but also a dedicated constructor that doesn't
   initialize (e.g. QPoint, QQuaternion, ...).
2) covers everything else. Default initialization of scalars and
   trivially constructible datatypes will leave them uninitialized.

A type which isn't trivially constructible will still get its default
constructor called (and possibly actually gets initialized); we can't
really do better than that, as we still have to construct objects and
start their lifetimes.

[ChangeLog][QtCore][QList] Added support for uninitialized construction
and resizing.

Change-Id: I32c285c7dddbf7e01475943f24e14e824bb13090
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-02-16 14:20:50 +01:00
Marc Mutz af051f9be2 QVarLengthArray: re-publish Prealloc as a nested PreallocatedSize
This gives users of the class easy access to the Prealloc template
argument, without having to write a pattern-matcher like

   template <typename T>
   constexpr qsizetype preallocated_size_v;
   template <typename T, qsizetype N>
   constexpr qsizetype preallocated_size_v<QVarLengthArray<T,N>> = N;

first.

[ChangeLog][QtCore][QVarLengthArray] Added PreallocatedSize nested
constant, equal to the Prealloc template argument.

Change-Id: I928eaa5e62967445cdd7b0c2759567483fdb8997
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2024-02-15 17:44:36 +00:00
Thiago Macieira 0d15c000ad qHash: backport the q(u)int128-to-quint64 reduction trick to 32-bit
I didn't do it in a template because the 32-bit code requires a
compatibility hack for Qt 6 and it's using an XOR of the high and low
parts.

Fixes: QTBUG-116080
Change-Id: I5dd50a1a7ca5424d9e7afffd17ae0ba5b9ff52f6
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-02-12 17:01:33 -08:00
Marc Mutz 1d7950c946 Add missing qHash(qu/int128) overloads
If we add the typedefs, we also need to add the qHash() overloads. See
code comments for the explanation of how it works. I chose to use an
addition to merge the upper and lower parts because of the comment in
QHashCombineCommutative's operator(), introduced by commit
91b44afdcb.

Found in 6.6 API-review, but didn't make the cut and then was
forgotten.

Drive-by fix long line nearby.

[ChangeLog][QtCore] Added qHash() overloads for quint128 and qint128.

Fixes: QTBUG-116054
Task-number: QTBUG-116080
Change-Id: If484aed08ba476e0eace800b719f435203100f3e
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2024-02-12 17:01:33 -08:00
Thiago Macieira 1845d43327 tst_QHashFunctions: make the consistency check table-driven
So we can test more values. Because we are testing more values, we can't
use QEXPECT_FAIL, because we can't guarantee a mismatch.

Pick-to: 6.7
Task-number: QTBUG-116077
Task-number: QTBUG-116080
Change-Id: I664b9f014ffc48cbb49bfffd17b021719e6d612f
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-02-12 17:01:33 -08:00
Marc Mutz e1f45ad818 QMap: add missing qHash() overload
Found in API review, but not deemed important enough to still get into
6.7.

Not implementing it for QMultiMap, because there we need to mod out
order of equivalent elements.

The GHS compiler acted up and tried to compile the noexcept
specification, hitting non-existing qHash(QVariant) for QVariantMap
and producing a hard error instead of SFINAE'ing out. As a
work-around, establish an artificial SFINAE-friendly context, but only
for that compiler.

[ChangeLog][QtCore][QMap/QHash] Added qHash() overload for QMap.

Change-Id: Ia7dbf488e8e5490962118e40581b7c4cc8ed95e5
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2024-02-09 20:33:05 +00:00
Marc Mutz f4cfc21dec QList: give the LWG 3346 #ifdef'ery a symbolic name
We'll need this in more places, so centralize its definition in
qcompilerdetection.h.

Amends 595b4e1a9b.

Pick-to: 6.7 6.6 6.5
Change-Id: I87f84cb9ff3ad339c000604423295180176f5799
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2024-02-08 17:43:59 +01:00
Tasuku Suzuki bd6d7d4d74 Remove extra semi-colons
Change-Id: I92fddb36cd136fd1bd627955f15d0559b9942d7e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2024-02-06 20:17:18 +09:00
Lucie Gérard ff1039c217 Change license for tests files
According to QUIP-18 [1], all tests file should be
LicenseRef-Qt-Commercial OR GPL-3.0-only

[1]: https://contribute.qt-project.org/quips/18

Pick-to: 6.7
Task-number: QTBUG-121787
Change-Id: I9657df5d660820e56c96d511ea49d321c54682e8
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
2024-02-04 09:56:42 +01:00
Thiago Macieira c5f22c54cb qHash: provide the long double overload on Darwin systems
Commit c0791ac76e didn't explain why it
was #ifdef'ed out. It's just an alias for double. Maybe compilers at the
time used to complain if you used it, but I can't make Apple's clang
produce a warning now.

Pick-to: 6.7
Change-Id: I664b9f014ffc48cbb49bfffd17b02293403e9571
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2024-02-03 07:33:00 -08:00
Marc Mutz 6504496c64 QBitArray: use QDataStream::SizeLimitExeeded where applicable
[ChangeLog][QtCore][QBitArray] Uses new
QDataStream::Status::SizeLimitExceeded now, where applicable (was:
WriteFailed, ReadCorruptData).

Pick-to: 6.7
Change-Id: If5a8db9c6b2f104b40266784d88cf7cad0b0ce73
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-02-03 08:33:14 +01:00
Marc Mutz 9219e8ff1d QBitArray: don't create invalid Qt 5 streams
Qt 5 streams cannot handle QBitArrays with more than INT_MAX bits,
even on 64-bit platforms, because of interface constraints (size_type
int).

Qt 6 can, so make sure to refuse serialization of oversized QBitArrays
to Qt-5-compatible streams.

[ChangeLog][QtCore][QBitArray] Now refuses to stream a QBitArray with
size() > INT_MAX to a Qt-5-compatible QDataStream.

Pick-to: 6.7 6.6 6.5 6.2
Change-Id: I263e27bd366757c8e0360dfd337948c44d00647a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2024-02-02 15:35:51 +01:00
Marc Mutz 2188ca2c5d QVersionNumber: make iterable
Since QVersionNumber doesn't have an existing way to modify individual
segments, provide only const_iterator.

[ChangeLog][QtCore][QVersionNumber] Added (const) iterators over
segments (begin()/end(), incl. c- and r- variants).

Change-Id: Ia9af70c2a9c59f630123894ad2c9f38031ef5b8f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-01-31 20:18:48 +00:00
Marc Mutz c6aa399d06 QBitArray: avoid overflow in size-to-storage calculations
Unlike other containers, a QBitArray's size() is not limited by
storage, but, esp. on 32-bit platforms, its size_type: A INT_MAX
size() QBitArray only requires 256MiB of storage.

So we can't rely on "won't happen in practice" here and need to avoid
the potential UB (signed overflow) in the (size + 7) / 8
logical-to-storage-size calculation by using unsigned arithmetic.

Use the opportunity to Extract Methods storage_size() and
allocation_size(), which differ by one (d[[0] contains the size() mod
8), making it clear what's what.

[ChangeLog][QtCore][QBitArray] Fixed a bug with QBitArrays whose
size() came within 7 of the size_type's maximum.

Pick-to: 6.7 6.6 6.5 6.2 5.15
Change-Id: I5d94bae9c9c210ba1e36f8cf03609125c81bd15d
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2024-01-30 22:28:19 +01:00
Marc Mutz 94e122c594 QSpan: make adl_begin() etc SFINAE-friendly
The definition of iterator_t, and, therefore, of is_compatible_range
depends on this, otherwise say, 0, is being treated as a valid range
and hits a hard error in adl_begin() when trying to call begin(int&).

TIL: decltype(auto) does _not_ SFINAE.

Fix by calculating the return type manually, re-enabing SFINAE.

Pick-to: 6.7 6.6
Change-Id: Icacd70554f4050ecaeb396c9ae60bc4f21a220c9
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-01-26 23:50:57 +01:00
Allan Sandfeld Jensen 92acc94fa9 Optimize QSet::unite
Done similar to intersect. This also improves one test, as we get one less detach, and makes it consistent with other results.

Change-Id: I4d08bf43e750c758b363f8e4fe1fe312a7a0cde4
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2024-01-20 08:55:06 +00:00
Marc Mutz 37e2aa7698 Dissociate QTypeRevision from QVersionNumber
They have nothing to do with each other, so give QTypeRevision its own
header and implementation file instead of piggy-backing on
QVersionNumber's.

Picking back to current LTS to incur the merge conflict only once, not
per (expected) follow-up change.

Amends ed080c64ae.

Pick-to: 6.7 6.6 6.5
Change-Id: I2fa5d0e68f95864126bc95e3d8154134eee85553
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2024-01-10 02:25:24 +00:00