Remove stray comment at the end of tst_qexplicitlyshareddatapointer.cpp
Pick-to: 6.6
Change-Id: I31a6c38002e56e7c43e527864ba3d9324950079f
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
QSpan is Qt's version of std::span. While we usually try not to
reimplement std functionality anymore, the situation is different with
QSpan. Spans are non-owning containers, so the usual impedance
mismatch between owning STL and Qt containers doesn't apply here:
QSpan implicitly converts to std::span and vice versa, making STL and
Qt APIs using spans completely interoperable.
We add QSpan mainly for two reasons: First, we don't want to wait
until we require C++20 in Qt and can use std::span. Second, in the
view of this author, some design decisions in std::span hurt the
primary use-case of spans: type-erasure for containers. This results
in two major deviations of QSpan from std::span: First, any rvalue
container is convertible to QSpan, allowing seamless passing of owning
containers to functions taking spans:
void sspan(std::span<T>);
void qspan(QSpan<T>);
std::vector<T> v();
sspan(v()); // ERROR: rvalue owning container
auto tmp = v();
sspan(tmp); // OK, lvalue
qspan(v()); // OK
This author believes that it's more helpful to have compilers and
static checkers warn about a particular wrong usage than to make
perfectly valid use-cases impossible or needlessly verbose to code.
The second deviation from std::span is that fixed-size span
constructors are also implicit. This isn't as clear-cut, because an
explicit QSpan{arg} isn't per-se bad. However, it means you can't
transparently change from a function taking decltype(arg) to one
taking QSpan and back. Since that's exactly what we intend to do in Qt
going forward, in the interest of source-compatibility, the ctors are
all implicit.
Otherwise, the API of QSpan follows the std::span API very
closely. Like std::span, QSpan isn't equality_comparable, because it's
not clear what equality means for spans (element-wise equal, or (ptr,
size)-wise equal?). The major API additions are Qt-ish versions of std
API functions: isEmpty() on top of empty() and sliced() instead of
subspan(). The (nullary) first()/last() functions (Qt speak for
front()/back()) clash with the std::span function templates of the
same name, so are not provided.
This patch adds QSpan as private API. We intend to make it public API
in the future.
Pick-to: 6.6
Fixes: QTBUG-108124
Change-Id: I3f660be90eb408b9e66ff9eacf5da4cba17212a6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
We need deduction guides to turn the AtomicPointer template argument
(the pointee) into a pointer:
QAtomicPointer<int> → QAtomicScopedValueRollback<int*>
Extend a test to cover pointers, too.
Fixes: QTBUG-115105
Pick-to: 6.6 6.5
Change-Id: Ib416c6a43e4da480b707a0bf6a10d186bbaad163
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
It's a bit cumbersome, but works, in principle, using CTAD.
Pick-to: 6.6 6.5 6.2
Task-number: QTBUG-114200
Change-Id: Ib7354180e870a695a978edabf684aedfcf9d9ecc
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Add the boilerplate standalone test prelude to each test, so that they
can be opened with an IDE without the qt-cmake-standalone-test script,
but directly with qt-cmake or cmake.
Boilerplate was added using the following scripts:
https://git.qt.io/alcroito/cmake_refactor
Manual adjustments were made where the code was inserted in the wrong
location.
Task-number: QTBUG-93020
Change-Id: I28b6d3815c5f43d2c33ea65764f6f3f8f129eaf3
Reviewed-by: Amir Masoud Abdol <amir.abdol@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
INTEGRITY has a pre-P1115 implementation of std::erase/erase_if that
returns void instead of the number of erased elements, so make q20's
implementation more specialized, so the compiler will pick it over
INTEGRITY's (Marc's idea from the code review).
Change-Id: I88d025a3f90cdd65f5bb73beb8a39e32ccf12d9b
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
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>
Implemented assign() methods for QByteArray 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
[ChangeLog][QtCore][QByteArray] Added assign().
Fixes: QTBUG-106199
Change-Id: I899b14d74e8f774face8690303efb8610ead95b5
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Refactor the 'CHECK' macro to eliminate the capacity check and
explicitly verify that no reallocation occurred. The previous
implementation had to pass constants to suppress the issue arising
from differing growth rates between implementations.
Additionally, improve the 'std::stringstream' versions of the test
by incorporating the correct values. In the previous implementation,
the usage of:
auto tData = V(9);
~~~
std::stringstream ss("9 9 ");
had several issues. Firstly, it used the wrong test data since the
container's value_type of '(char) 9' resulted in a tab character '\t',
which was not accurately reflected in the stringstream assignment.
Secondly, this value caused problems in how stringstreams interprets it.
To address these issues, let's make the following improvements:
1. Use a default test value of 65 instead of (char) 9. This value, which
represents the character 'A', is less likely to cause errors and is more
intuitive.
2. Use the tData variable for the assignments in the stringstream. This
ensures that the correct data from the container is used.
3. Change the test value between the assign() calls to verify that the
container's contents are successfully overwritten.
These changes ensure, that the test cases are more accurate and
reliable.
Amends: 3b0536bbe8.
Change-Id: I9441c4818106bf93e93a1a5d2d2d54c89d80e7b0
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
While std::vector::assign() returns void, std::basic_string::assign()
returns std::basic_string&. In Qt, we want to be consistent between
{QVLA,QList,QString,QByteArray}::assign(), and returning *this is the
more general solution, so do that.
Task-number: QTBUG-106196
Task-number: QTBUG-106200
Change-Id: I2689b4af032ab6fb3f8fbcb4d825d5201ea5abeb
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Implemented assign() methods for QList to align with the criteria of
std::vector, addressing the previously missing functionality.
Reference:
https://en.cppreference.com/w/cpp/container/vector/assign
[ChangeLog][QtCore][QList] Added assign().
Fixes: QTBUG-106196
Change-Id: I5df8689c020dafde68d2cd7d09c769744fa8f137
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This file, like the majority of qtbase, uses a space between template
and the opening of the template argument list. Add it.
Change-Id: I927cb2b1b9620ae108e913343d995373493e8981
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This is handled by the Objective-C runtime nowadays, where it will
abort if the situation is detected, with the option to break on
objc_autoreleasePoolInvalid to debug the situation.
Pick-to: 6.5
Change-Id: Idf2c4aacc77e41a3deebf270303f4f13cfb0819b
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
The options included by --help-all, although they are "specific to
Qt", are "specific" to all Qt applications, so - in the present
context, of QCommandLineParser - not specific at all. It's the options
described by -h that are specific, to the present command; the Qt
options are generic (in the present context).
So rework the help string for --help-all itself and the documentation
of the function. It had, in any case, an overly-complex first line,
that descended into too much detail. Updated test to match.
Pick-to: 6.5
Task-number: QTBUG-111228
Change-Id: I06da0af41be60e6e1b7616984001ddb9ca33aad6
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: David Faure <david.faure@kdab.com>
The parameter passed to reserve() is just a hint. The container
implementation is free to choose a larger capacity, and some do
(e.g. QList in prepend optimization mode).
Fix the test by querying the container for its post-make<>()
capacity() and taking a larger-than-expected initial capacity() into
account when later re-checking the capacity().
Change-Id: Id8f26f14e8df9d685ca2387ec4a52d74fea7cb9d
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
It took me a sec to figure out the relation between the comment and
the code line following it. Make it easier for the next guy and add a
bit more infos.
Amends 7cbdc8abbd.
Change-Id: I4ff2d9a52aef643a92339df32cc86f686a689a9a
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
We use a single line per test slot everywhere else, ignoring even
line-length limitations, to keep the function names aligned for easier
parsing.
Amends 7cbdc8abbd.
Change-Id: Iaf2941aae88392d407d688fc4a7537fcdc0a5851
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
STL algorithms, in general, don't specify how often the function
objects passed to them are copied during the run of the
algorithm.
While generate_n is above any reasonable suspicion of copying the
function object after the first invocation, passing a mutable lambda
containing the counter is still an anti-pattern we don't want people
to copy.
Fix in the usual way, by keeping the counter external to the lambda.
As a drive-by, replace post- with pre-increment.
Amends dc091e7443.
Pick-to: 6.5 6.2
Change-Id: I9c44e769fd41e5f7157179a2be4c3534424cf913
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Removing a few unused variables in auto tests that were triggering
`-Wunused-but-set-variable`.
Pick-to: 6.5
Change-Id: I74bd0d7335d8bddeb18687b18c8a8be965f9fa20
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
QMultiHash has access to two sizes: one of them is shared with QHash,
stored in QHashPrivate::Data::size, which counts keys; the other, which
is what our public size() function returns, is stored in
QMultiHash::m_size and counts plain (key,value) entries. We forgot to
update it in the non-const operator[] that created a node.
I've reviewed the rest of the code and can't find any more places where
the item count may be changed and m_size isn't updated.
[ChangeLog][QtCore][QMultiHash] Fixed a bug that caused an element that
was created by operator[] to not be counted, resulting in a hash map
with an incorrect element count and which could cause an assertion
failure depending on how the hash was later mutated.
Fixes: QTBUG-112534
Pick-to: 6.2 6.4 6.5
Change-Id: Idd5e1bb52be047d7b4fffffd17527ec274e1d99e
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
In C++17, unqualified lookup doesn't find function templates that
require ADL from a call with explicit template arguments, unless
another function template of that name is in scope (otherwise, the <
is parsed as operator less-than instead).
P0846, merged for C++20, fixes this to repeat the name lookup, parsing
the < as indicating a template.
We have API in Qt (Tuple Protocol for some types, e.g. QPoint) that
work for the purpose of Structured Bindings, but don't work for manual
unqualified calls when P0846 semantics are missing, and we're adding
more, to QVariant, so add a macro to handle the issue.
The macro simply declares a function template overload of the given
name for a throw-away struct, thereby bringing, for that one name,
P0846 semantics into C++17.
When we require C++20, we can drop this again.
Amends:
- fb6b7869e8 for QPoint(F)
- 8ae9431c79 for QMargins(F)
- 0e22001a3b for the rest
[ChangeLog][QtCore][QSize/F, QMargins/F, QPoint/F] Fixed manual
get<I>() calls (Tuple Protocol) in C++17 mode.
Task-number: QTBUG-111598
Change-Id: I2ffaef12c5bb6d82f75ce78a7c03c6789dfa0691
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
We test setKey() in repeated_setKey() these days, so speed up the test
of the test suite ever so slightly by passing the key to the ctor
instead of an explicit setKey() call.
Pick-to: 6.5
Change-Id: Ia2378c0f59cbfa9d95a0f3665b06655332247e2c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
When this code was using QByteArray, whose data() is never nullptr,
the strings presented to the underlying C APIs were always valid NTSs
(nullptr is not a valid NTS).
With QByteArrayView, or with QT5_NULL_STRINGS != 1, this is no longer
the case. Check that all implementations are fine with that.
Pick-to: 6.5 6.4
Change-Id: I78251288a4784440af4a2daf095aed7c53867287
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
QCryptographicHash is move-only these days, so
QMessageAuthenticationCode should not be left behind.
[ChangeLog][QtCore][QMessageAuthenticationCode] Added move
constructor, move assignment operator and swap() function.
Fixes: QTBUG-111677
Change-Id: I420f24c04828e8ad7043a9e8c9e7e2d47dd183e0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Previous setup of the test was failing in minimal static build if built
using the unity build because of the explicit inclusion of the qtcore
source files. In order to resolve this, I removed the inclusion of
qtcore's headers and made the test private.
Pick-to: 6.5
Task-number: QTBUG-109394
Change-Id: Id1c7b3b65ca2078354c235a718ff3e93a65362e6
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
All the other overloads are implemented using the new one.
Windows change relies on the pre-check in the code review making sure it
compiles.
[ChangeLog][QtCore][QThread] Added sleep(std::chrono::nanoseconds)
overload.
Task-number: QTBUG-110059
Change-Id: I9a4f4bf09041788ec9275093b6b8d0386521e286
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
state->rate is always larger than or equal to state->bitsInQueue;
when bitsInQueue == rate the queue is consumed and bitsInQueue is set to
0 again.
Done-with: Marc Mutz <marc.mutz@qt.io>
Pick-to: 6.5.0 6.5 6.4.3 6.4 6.2 5.15
Change-Id: I56d268a19fb3cd542cc027edc962253f09d97a14
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
... to make large data usable from other test functions.
Pick-to: 6.5 6.5.0 6.4 6.4.3 6.2
Change-Id: I302070121a8bb49f373c7711bc3ab9e6418874ef
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Also add one for types that are neither copy- nor move-constructible.
In contrast to resize(n), the QVLA(n) ctor worked for such types, so
make sure it stays that way.
Pick-to: 6.5 6.4 6.4.3 6.2 5.15
Change-Id: If54fbc9dd6a4808175c4bcb0ffb492b33c879746
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Use it in a few places.
[ChangeLog][QtCore][QMessageAuthenticationCode] Added
QCryptographicHash-style resultView().
Change-Id: I745d71f86f9c19c9a9aabb2021c6617775dab1cf
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Add Algorithm::NumAlgorithms and use it to iterate over all
statically-available algorithms, querying their hashLengthInternal().
This avoids having to statically_assert(<= MaxHashLength) everywhere,
and auto-adjusts the buffer size in SHA1_ONLY builds.
Yes, the extra case labels for NumAlgorithms are a nuisance, but at
least the compiler will remind us when we forget, unlike a missing
static_cast(<= MaxHashLength) that might easily be forgotten.
Adjust the test (which iterates over the QMetaEnum for
QCryptographicHash::Algorithm, so finds NumAlgorithms and tries to
pass it to the hash() function which responds with a
Q_UNREACHABLE(). Only test hashLength() == 0 for that enum value.
Pick-to: 6.5
Change-Id: I70155d2460464f0b2094e136eb6bea185effc9d5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
It was confusing entry capacity with the bucket capacity. The value
maxNumBuckets() returned was the maximum number of entries. This issue
was harmless: we would just fail to cap the maximum to an allocatable
size. But the array new[] in the Data constructors would have capped the
maximum anyway (by way of throwing std::bad_alloc).
So instead of trying to calculate what the maximum bucket count is so we
can cap at that, simplify the calculation of the next power of 2 while
preventing it from overflowing in our calculations. We continue to rely
on new[] throwing when we return count that is larger than the maximum
allocatable.
This commit changes the load factor for QHashes containing exactly a
number of elements that is exactly a power of two. Previously, it would
be loaded at 50%, now it's at 25%. For this reason, tst_QSet::squeeze
needed to be fixed to depend less on the implementation details.
Pick-to: 6.5
Change-Id: I9671dee8ceb64aa9b9cafffd17415f3856c358a0
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
I don't begin to understand the semantics of the trackers here, but
whatever they are, they break with the fallback std::swap() 3-moves
implementation and lose track of alive objects, so provide an ADL swap
that does the right thing.
Amends dd58ddd5d9 (I think).
Pick-to: 6.5 6.4 6.2 5.15
Change-Id: I1cd49c95dca2d103a26c2c7ac0a896929135a6c8
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Implemented assign() methods for QVarLengthArray to align
with the criteria of std::vector, addressing the previously
missing functionality.
Reference:
https://en.cppreference.com/w/cpp/container/vector/assign
[ChangeLog][QtCore][QVarLengthArray] Added assign().
Fixes: QTBUG-106200
Change-Id: If671069808ff561b0f4c77b6c7f7aca360a0c663
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
The growBy() function takes the _increment_ of the size(), so needs to
add size() to increment for the call to realloc().
Add a test which hangs (vanilla build) or explodes (valgrind build)
without the fix.
Amends 26b227e128.
Done-with: Eirik Aavitsland <eirik.aavitsland@qt.io>
Pick-to: 6.5 6.4
Fixes: QTBUG-110412
Change-Id: I7ea91342fdcb779825c88013a3f86ba6d90ef530
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Despite being move-only, std::vector<unique_ptr> advertizes
is_copyable:
https://quuxplusone.github.io/blog/2020/02/05/vector-is-copyable-except-when-its-not/
Our combined reallocation and resizing function, reallocate_impl(),
runs afoul of this when it uses std::is_copyable in a constexpr-if to
implement resize(n, v) without running into problems with move-only
types: the trait is true, but actual instantation runs into a
static_assert in the STL implementation.
To fix, move the problematic resize functionality out of
reallocate_impl() and into the resp. resize_impl overloads. The shrink
functionality remains in reallocate_impl(), because there are many
more users, and it only requires destructible<T>, which isn't
constraining at all.
Amends a00a1d8806.
Fixes: QTBUG-109745
Pick-to: 6.5 6.4
Change-Id: Ibc5b9cf5375108eb3d8f6c8a16d4fd02dadd73b1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Just describe the row instead. We'd lose the original input in case of
failure, so I added a class to print that value on destruction. Example:
FAIL! : tst_QAlgorithms::countLeading64(0) Compared values are not the
same
Actual (qCountLeadingZeroBits(value)): 63
Expected (expected) : 64
Loc: [tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp(374)]
QWARN : tst_QAlgorithms::countLeading64(0) Original value was 0x1
Pick-to: 6.4 6.5
Fixes: QTBUG-109958
Change-Id: I69ecc04064514f939896fffd1738b1119cd80cf8
Reviewed-by: Dimitrios Apostolou <jimis@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
In preparation to their deprecation / removal.
Change-Id: Ia073a9f7caabbc06063a1e416b23cdb12788b283
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
For QSet, the key_type is const, so can't test assiging to it.
Pick-to: 6.4
Change-Id: I9d363ef3fe52646b937d6a422227b19c48fdaf1f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
qhashfunctions.h defines a catch-all 2-arguments qHash(T, seed)
in order to support datatypes that implement a 1-argument overload
of qHash (i.e. qHash(Type)). The catch-all calls the 1-argument
overload and XORs the result with the seed.
The catch-all is constrained on the existence of such a 1-argument
overload. This is done in order to make the catch-all SFINAE-friendly;
otherwise merely instantiating the catch-all would trigger a hard error.
Such an error would make it impossible to build a type trait that
detects if one can call qHash(T, size_t) for a given type T.
The constraint itself is called HasQHashSingleArgOverload and lives in a
private namespace.
It has been observed that HasQHashSingleArgOverload misbehaves for
some datatypes. For instance, HasQHashSingleArgOverload<int> is actually
false, despite qHash(123) being perfectly callable. (The second argument
of qHash(int, size_t) is defaulted, so the call *is* possible.)
--
Why is HasQHashSingleArgOverload<int> false?
This has to do with how HasQHashSingleArgOverload<T> is implemented: as
a detection trait that checks if qHash(declval<T>()) is callable.
The detection itself is not a problem. Consider this code:
template <typename T>
constexpr bool HasQHashSingleArgOverload = /* magic */;
class MyClass {};
size_t qHash(MyClass);
static_assert(HasQHashSingleArgOverload<MyClass>); // OK
Here, the static_assert passes, even if qHash(MyClass) (and MyClass
itself) were not defined at all when HasQHashSingleArgOverload was
defined.
This is nothing but 2-phase lookup at work ([temp.dep.res]): the
detection inside HasQHashSingleArgOverload takes into account the qHash
overloads available when HasQHashSingleArgOverload was declared, as well
as any other overload declared before the "point of instantiation". This
means that qHash(MyClass) will be visible and detected.
Let's try something slightly different:
template <typename T>
constexpr bool HasQHashSingleArgOverload = /* magic */;
size_t qHash(int);
static_assert(HasQHashSingleArgOverload<int>); // ERROR
This one *does not work*. How is it possible? The answer is that 2-phase
name lookup combines the names found at definition time with the names
_found at instantiation time using argument-dependent lookup only_.
`int` is a fundamental type and does not participate in ADL. In the
example, HasQHashSingleArgOverload has actually no qHash overloads to
even consider, and therefore its detection fails.
You can restore detection by moving the declaration of the qHash(int)
overload *before* the definition of HasQHashSingleArgOverload, so it's
captured at definition time:
size_t qHash(int);
template <typename T>
constexpr bool HasQHashSingleArgOverload = /* magic */;
static_assert(HasQHashSingleArgOverload<int>); // OK!
This is why HasQHashSingleArgOverload<int> is currently returning
`false`: because HasQHashSingleArgOverload is defined *before* all the
qHash(fundamental_type) overloads in qhashfunctions.h.
--
Now consider this variation of the above, where we keep the qHash(int)
overload after the detector (so, it's not found), but also prepend an
Evil class implicitly convertible from int:
struct Evil { Evil(int); };
size_t qHash(Evil);
template <typename T> constexpr bool HasQHashSingleArgOverload = /* magic */;
size_t qHash(int);
static_assert(HasQHashSingleArgOverload<int>); // OK
Now the static_assert passes. HasQHashSingleArgOverload is still not
considering qHash(int) (it's declared after), but it's considering
qHash(Evil). Can you call *that* one with an int? Yes, after a
conversion to Evil.
This is extremely fragile and likely an ODR violation (if not ODR, then
likely falls into [temp.dep.candidate/1]).
--
Does this "really matter" for a type like `int`? The answer is no. If
HasQHashSingleArgOverload<int> is true, then a call like
qHash(42, 123uz);
will have two overloads in its overloads set:
1) qHash(int, size_t)
2) qHash(T, size_t), i.e. the catch-all template. To be pedantic,
qHash<int>(const int &, size_t), that is, the instantiation of the
catch-all after template type deduction for T (= int)
([over.match.funcs.general/8]).
Although it may look like this is ambiguous as both calls have perfect
matches for the arguments, 1) is actually a better match than 2) because
it is not a template specialization ([over.match.best/2.4]).
In other words: qHash(int, size_t) is *always* called when the argument
is `int`, no matter the value of HasQHashSingleArgOverload<int>. The
catch-all template may be added or not to the overload set, but it's
a worse match anyways.
--
Now, let's consider this code:
enum MyEnum { E1, E2, E3 };
qHash(E1, 42uz);
This code compiles, although we do not define any qHash overload
specifically for enumeration types (nor one is defined by MyEnum's
author).
Which qHash overload gets called? Again there are two possible
overloads available:
1) qHash(int, size_t). E1 can be converted to `int` ([conv.prom/3]),
and this overload selected.
2) qHash(T, size_t), which after instantiation, is qHash<MyEnum>(const
MyEnum &, size_t).
In this case, 2) is a better match than 1), because it does not require
any conversion for the arguments.
Is 2) a viable overload? Unfortunately the answer here is "it depends",
because it's subject to what we've learned before: since the catch-all
is constrained by the HasQHashSingleArgOverload trait, names introduced
before the trait may exclude or include the overload.
This code:
#include <qhashfunctions.h>
enum MyEnum { E1, E2, E3 };
qHash(E1, 42uz);
static_assert(HasQHashSingleArgOverload<MyEnum>); // ERROR
will fail the static_assert. This means that only qHash(int, size_t) is
in the overload set.
However, this code:
struct Evil { Evil(int); };
size_t qHash(Evil);
#include <qhashfunctions.h>
enum MyEnum { E1, E2, E3 };
qHash(E1, 42uz);
static_assert(HasQHashSingleArgOverload<MyEnum>); // OK
will pass the static_assert. qHash(Evil) can be called with an object of
type MyEnum after an user-defined conversion sequence
([over.best.ics.general], [over.ics.user]: a standard conversion
sequence, made of a lvalue-to-rvalue conversion + a integral promotion,
followed by a conversion by constructor [class.conv.ctor]).
Therefore, HasQHashSingleArgOverload<MyEnum> is true here; the catch-all
template is added to the overload set; and it's a best match for the
qHash(E1, 42uz) call.
--
Is this a problem? **Yes**, and a huge one: the catch-all template does
not yield the same value as the qHash(int, size_t) overload. This means
that calculating hash values (e.g. QHash, QSet) will have different
results depending on include ordering!
A translation unit TU1 may have
#include <QSet>
#include <Evil>
QSet<MyEnum> calculateSet { /* ... */ }
And another translation unit TU2 may have
#include <Evil>
#include <QSet> // different order
void use() {
QSet<MyEnum> set = calculateSet();
}
And now the two TUs cannot exchange QHash/QSet objects as they would
hash the contents differently.
--
`Evil` actually exists in Qt. The bug report specifies QKeySequence,
which has an implicit constructor from int, but one can concoct infinite
other examples.
--
Congratulations if you've read so far.
=========================
=== PROPOSED SOLUTION ===
=========================
1) Move the HasQHashSingleArgOverload detection after declaring the
overloads for all the fundamental types (which we already do anyways).
This means that HasQHashSingleArgOverload<fundamental_type> will now
be true. It also means that the catch-all becomes available for all
fundamental types, but as discussed before, for all of them we have
better matches anyways.
2) For unscoped enumeration types, this means however an ABI break: the
catch-all template becomes always the best match. Code compiled before
this change would call qHash(int, size_t), and code compiled after this
change would call the catch-all qHash<Enum>(Enum, size_t); as discussed
before, the two don't yield the same results, so mixing old code and new
code will break.
In order to restore the old behavior, add a qHash overload for
enumeration types that forwards the implementation to the integer
overloads (using qToUnderlying¹).
(Here I'm considering the "old", correct behavior the one that one gets
by simply including QHash/QSet, declaring an enumeration and calling
qHash on it. In other words, without having Evil around before including
QHash.)
This avoids an ABI break for most enumeration types, for which one
does not explicitly define a qHash overload. It however *introduces*
an ABI break for enumeration types for which there is a single-argument
qHash(E) overload. This is because
- before this change, the catch-all template was called, and that
in turn called qHash(E) and XOR'ed the result with the seed;
- after this change, the newly introduced qHash overload for
enumerations gets called. It's very likely that it would not give
the same result as before.
I don't have a solution for this, so we'll have to accept the ABI
break.
Note that if one defines a two-arguments overload for an enum type,
then nothing changes there (the overload is still the best match).
3) Make plans to kill the catch-all template, for Qt 7.0 at the latest.
We've asked users to provide a two-args qHash overload for a very long
time, it's time to stop working around that.
4) Make plans to switch from overloading qHash to specializing std::hash
(or equivalent). Specializations don't overload, and we'd get rid of
all these troubles with implicit conversions.
--
¹ To nitpick, qToUnderlying may select a *different* overload than
the one selected by an implicit conversion.
That's because an unscoped enumeration without a fixed underlying type
is allowed to have an underlying type U, and implicitly convert to V,
with U and V being two different types (!).
U is "an integral type that can represent all the enumerator values"
([dcl.enum/7]). V is selected in a specific list in a specific order
([conv.prom]/3). This means that in theory a compiler can take enum E {
E1, E2 }, give it `unsigned long long` as underlying type, and still
allow for a conversion to `int`.
As far as I know, no compiler we use does something as crazy as that,
but if it's a concern, it needs to be fixed.
[ChangeLog][Deprecation Notice] Support for overloads of qHash with only
one argument is going to be removed in Qt 7. Users are encouraged to
upgrade to the two-arguments overload. Please refer to the QHash
documentation for more information.
[ChangeLog][Potentially Binary-Incompatible Changes] If an enumeration
type for which a single-argument qHash overload has been declared is
being used as a key type in QHash, QMultiHash or QSet, then objects of
these types are no longer binary compatible with code compiled against
an earlier version of Qt. It is very unlikely that such qHash overloads
exist, because enumeration types work out of the box as keys Qt
unordered associative containers; users do not need to define qHash
overloads for their custom enumerations. Note that there is no binary
incompatibity if a *two* arguments qHash overload has been declared
instead.
Fixes: QTBUG-108032
Fixes: QTBUG-107033
Pick-to: 6.2 6.4
Change-Id: I2ebffb2820c553e5fdc3a341019433793a58e3ab
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The "qhash" test relied on the fact that those four elements would
produce a different order with a zero and a non-zero seed. But since
commit b057e32dc4 removed the setting of a
deterministic non-zero seed, this test had a 1 in 4! chance of failing.
Since 4! = 24, 128 retries should be more than enough to ensure we do
find at least hash seed that provokes a different order.
Fixes: QTBUG-107725
Change-Id: I3c79b7e08fa346988dfefffd171ee61b79ca5489
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
The row 27 that was positioned before row 01, as if it were meant to
be numbered row 00, was identical to the row 27 that appeared after
row 26. Since row 26 was the other case dealing with the null
QRectF(), I kept the one after it instead of renumbering row 00 and
deleting row 27.
Change-Id: I3585839184233f1f1629280ac9e5b25110c155c0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Use key(i) rather than valueToKey(value) as the Sha3_* alias Kekkak_*
or RealSha3_*. This way, we still test all members of the enum,
without duplicating row keys (albeit the aliases duplicate values).
Change-Id: I6acba5ffdf5b68294031d609a76b37ca8fad9d94
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Both countBits() and datastream() had two copies of an all-zeros test
with 35 zeros. Removed the second, in each case.
Change-Id: I5dec4765236ae870c30828dae0f04b8902a100f0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Add at least a few, so size() isn't completely untested.
Pick-to: 6.4 6.2 5.15
Change-Id: I500d28f7efb30ab578808d8fefb6ea57949edc2e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
A violation of coding style (requiring braces on multi-line bodies
of conditionals) was accompanied by a mis-indented else block.
Fix a long line while I'm about it.
Change-Id: Ibe9cf15eadbe9ef58138d7876e5e2c5a14a92fd4
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Pull out the arbitrary factor of three as a named constant and
document its arbitrariness once.
Pull out the mask and bit used in each function's loop to the outer
layer of the loop, since they don't depend on the inner loop variable
(or the random value generated in that loop).
Use QTest::addRow() instead of constructing a string to pass to
newRow().
Change-Id: Ifacbcb390e00828fd47f51b0c73d0ad5f6bc8bdb
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
We've been requiring C++17 since Qt 6.0, and our qAsConst use finally
starts to bother us (QTBUG-99313), so time to port away from it
now.
Since qAsConst has exactly the same semantics as std::as_const (down
to rvalue treatment, constexpr'ness and noexcept'ness), there's really
nothing more to it than a global search-and-replace, with manual
unstaging of the actual definition and documentation in dist/,
src/corelib/doc/ and src/corelib/global/.
Task-number: QTBUG-99313
Change-Id: I4c7114444a325ad4e62d0fcbfd347d2bbfb21541
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Given a QTaggedPointer, users may write
taggedPtr = {};
to mean "reset it". This is error-prone: due to overload resolution,
this actually ends up calling QTaggedPointer<T>::operator=(T *),
which changes the pointer but *not* the tag, and not the implicitly
declared QTaggedPointer<T>:operator=(const QTaggedPointer<T> &)
which would reset both pointer and tag.
Given the idiomatic usage of {} is indeed to perform a full reset (cf.
std::exchange(obj, {}), std::take, etc.), work around this by disabling
the operator= overload for pointers in case an initializer list is
passed. In other words, make `={}` fall back to the implicitly
declared overload.
Note, this breaks some usages, such as
taggedPtr = {rawPtr};
but at least we get a compile error for these, and they don't look
common at all.
[ChangeLog][QtCore][QTaggedPointer] The operator assignment
taking a raw pointer has been reimplemented in order to avoid
subtle issues when assigning `{}` to a QTaggedPointer. This will
cause code that assigns a braced-init-list to a QTaggedPointer object
to stop compiling (for instance, `tagPtr = {ptr}` is now ill-formed).
Change-Id: I5e572a9b0f119ddb2df17f1797934933dff2ba7b
Task-number: QTBUG-106070
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Inserting the same key repeatedly with QMultiHash will not
test rehashing behavior because in Qt6 those entries all
end up in a linked list.
Pick-to: 6.4
Change-Id: I78c45eed0f35a13af6d6da75d7189a6933750f13
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
These tested results are all wrong and caused by internal overflows.
Note the behavior can not be fixed either as it involves moving an
already maximized QRect, which can not be done without overflow.
Change-Id: If35db68102889012c56eb149fe49bc48954d3422
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
This can be helpful when you calculate multiple hashes, store them in a
vector and you want to know which result belongs to which algorithm.
[ChangeLog][QtCore][QCryptographicHash] Added getter algorithm().
Change-Id: Ifcf78536f215619a6e2e3035a95598327d0ed733
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This adds a move constructor, a move assignment operator and a swap
function to QCryptographicHash. This can (to name one example) be useful
when you want to store multiple hashes in a vector.
[ChangeLog][QtCore][QCryptographicHash] Added move constructor, move
assignment operator and swap() function.
Change-Id: Id54594fa69104ec25ad78581f962a021e85531c2
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
And include qcore_mac_p.h where needed.
Task-number: QTBUG-99313
Change-Id: Idb1b005f1b5938e8cf329ae06ffaf0d249874db2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
It does a check to ensure you aren't comparing outside the container.
Fixes: QTBUG-106001
Pick-to: 6.2 6.3 6.4
Change-Id: Ic6547f8247454b47baa8fffd170eef346b7f4f24
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
The QScopedPointer::take() call in comparison() test was used to
avoid a double-deletion error, because the test is creating two
QScopedPointer instances referencing the same memory.
Avoid the take() call by providing a custom DummyDeleter and
managing the memory by the extarnal std::unique_ptr.
As the test now has no test-cases for QScopedPointer::take()
calls, create a new test for this deprecated API, and guard
it with QT_DEPRECATED_SINCE checks.
Task-number: QTBUG-104858
Change-Id: Iecc28d44d76c9ce5835e6b1a1df7db30e2a9ca25
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The most common changes are:
* removing the explicit tests for deprecated APIs
* QMultiMap::insertMulti() -> QMultiMap::insert()
* QMultiMap::insert(QMultiMap) -> QMultiMap::unite(QMultiMap)
Add separate tests for the deprecated APIs, and guard them
with QT_DEPRECATED_SINCE() checks.
Task-number: QTBUG-104858
Change-Id: Ifb79212d07f20028d93d75f2b32ec3785cc93b22
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
These functions are marked as deprecated in future Qt releases.
Task-number: QTBUG-104858
Change-Id: I25d2932455d8c9e3e2d722b1c48fc2cfa2d1e679
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Those were workarounds to passing a comma to a macro, but there are ways
around it. The simplest is to just use variadic macros; another, which
has been applied to Q_DECLARE_METATYPE for a long time, is to define an
alias to the thing you're trying to use.
Change-Id: Ie4bb662dcb274440ab8bfffd17097fbf0c53eabc
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
CMakeLists.txt and .cmake files of significant size
(more than 2 lines according to our check in tst_license.pl)
now have the copyright and license header.
Existing copyright statements remain intact
Task-number: QTBUG-88621
Change-Id: I3b98cdc55ead806ec81ce09af9271f9b95af97fa
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
QScopedValueRollback has a few users that apply it on QAtomicInt,
which happens to work as QAtomicInt is copy-constructible and its
ctors are implicit.
But that's of course nonsense. We don't need to store the oldValue in
an atomic, nor do we need to pass the new value into the ctor as an
atomic.
So, add a QAtomicScopedValueRollback which works on std::atomic as
well as the Qt atomics, but distinguishes between the reference (which
is atomic) and the value (which isn't), and use it in one of the
users, tst_QList.
Keep it private until we know whether there's an actual need for this.
The test is a copy of tst_qscopedvaluefallback, so the occasional
oddity (like atomic op*=) should be ignored.
Task-number: QTBUG-103835
Change-Id: I3c05b3e51f465698657a02ca5521ed465386e9a6
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
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>
When calling QHash::reserve(), or when creating the
internal QHashPrivate::Data structure, the value 0
for the size parameter is reserved for performing
the squeeze operation.
However commit 8a984ab772
broke it, by using the 0 value in QHashPrivate::Data
constructors as a mark that no resizing needs to be done.
This patch reverts the problematic commit (also applying
some later fixes to the code), and adds the missing
tests for Q[Multi]Hash::squeeze().
Pick-to: 6.3 6.2
Change-Id: Id644df7b2beb008e6a37b2c89b709adfbd893e25
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Calling Q[Multi]Hash::reserve(n) when n is much smaller than the
current amount of elements in the hash, could result in an infinite
loop, because at some point the algorithm could not find a free bucket
for the element.
Fixing it by returning early if the new desired capacity is less than
current.
Fixes: QTBUG-102067
Pick-to: 6.3 6.2
Change-Id: I38ef0b2168c4e2a317eedf91b2155b1fdffb1c27
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
QList and QString had them, so add them to QByteArray and
QVarLengthArray, too.
In the QVLA case, we need to jump though a hoop or two to avoid having
to duplicate all the reallocation logic. Nothing a few template tricks
cannot solve.
[ChangeLog][QtCore][QByteArray] Added resize(n, ch) overload.
[ChangeLog][QtCore][QVarLengthArray] Added resize(n, v) overload.
Fixes: QTBUG-102270
Change-Id: I0d281ae5b574f440f682e4a62427b434dcf5b687
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Don't mix unsigned and signed types in comparisons.
Pick-to: 6.3
Change-Id: Ia4ba9c114177425a21cadc8cafe8179928315a5d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
That is, insert() doesn't overwrite an existing entry, and range
insert inserts the first of equivalent keys' values, not the last.
This allowed this author to optimize the implementation of
makeUnique() to a O(N) algorithm (was: O(N²)). Said optimization would
have been possible with the old semantics, too, but I wrote the
algorithm first and only then noticed the broken insert() behavior is
present on QFlatMap, too, so I decided not to let good code go to
waste and to fix both problems at the same time.
In order to give users a hint of the changed semantics, make the new
API opt-in until Qt 6.5, so Qt 6.4 ships with the both the old and the
new semantics disabled, where they contradict.
Fixes: QTBUG-100092
Change-Id: Ic96d8bfe6bed9068dbe8c0d7171bd8921050fd95
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Our associative containers' iterator's value_type isn't a destructurable
type (yielding key/value). This means that something like
for (auto [k, v] : map)
doesn't even compile -- one can only "directly" iterate on the
values. For quite some time we've had QKeyValueIterator to allow
key/value iteration, but then one had to resort to a "traditional" for
loop:
for (auto i = map.keyValueBegin(), e = keyValueEnd(); i!=e; ++i)
This can be easily packaged in an adaptor class, which is what this
commmit does, thereby offering a C++17-compatible way to obtain
key/value iteration over associative containers.
Something possibly peculiar is the fact that the range so obtained is
a range of pairs of references -- not a range of references to pairs.
But that's easily explained by the fact that we have no pairs to build
references to; hence,
for (auto &[k, v] : map.asKeyValueRange())
doesn't compile (lvalue reference doesn't bind to prvalue pair).
Instead, both of these compile:
for (auto [k, v] : map.asKeyValueRange())
for (auto &&[k, v] : map.asKeyValueRange())
and in *both* cases one gets references to the keys/values in the map.
If the map is non-const, the reference to the value is mutable.
Last but not least, implement pinning for rvalue containers.
[ChangeLog][QtCore][QMap] Added asKeyValueRange().
[ChangeLog][QtCore][QMultiMap] Added asKeyValueRange().
[ChangeLog][QtCore][QHash] Added asKeyValueRange().
[ChangeLog][QtCore][QMultiHash] Added asKeyValueRange().
Task-number: QTBUG-4615
Change-Id: Ic8506bff38b2f753494b21ab76f52e05c06ffc8b
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
The existing API of QFlatMap did not allow efficient removal of
elements:
- std::remove_if does not apply, because it works by moving elements
back in the range onto those that need to be removed, which doesn't
work in flat_map's case, because, like for all associative
containers, the key in value_type is const.
- The node-based erase-loop (over it = cond ? c.erase(it) :
std::next(it)) works, but, unlike in traditional associative
containers, is quadratic, because flat_map::erase is a linear
operation.
According to Stepanov's principle of Efficient Computational Basis
(Elements of Programming, Section 1.4), we're therefore missing API.
Add it.
I couldn't make up my mind about the calling convention for the
predicate and, despite having authored a merged paper about erase_if,
can never remember what the predicate is supposed to take, so be fancy
and accept all: (*it), (it.key(), it.value()), (it.key()). This means
that unary predicates can either not be generic or must be properly
constrained to distinguish between pair<const K, V> and K, but that's
not necessarily a bad thing.
There's no reason to supply a Qt-ified removeIf on top of the standard
name, because this is private API and doubling the names would do
nothing except double the testing overhead.
Fixes: QTBUG-100983
Change-Id: I12545058958fc5d620baa770f92193c8de8b2d26
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
- current INTEGRITY development pack don't support denormals for float and double.
All values are rounded to 0.
Task-number: QTBUG-99123
Pick-to: 6.2 6.3
Change-Id: Iaaacdc4210c7ac2ec3ec337c61164a1ade0efb01
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
... which implements or assumes something about the
broken^Wnon-STL-compliant insertion behavior.
Once this has integrated into all module dependencies, we can
re-implement these APIs using STL-compatible semantics.
Task-number: QTBUG-100092
Change-Id: I54f4f5ce7addd9543866d2c399f48aff50983b88
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
The macOS standard library doesn't have std::contiguous_iterator yet, and
it doesn't seem like libc++ has it either.
Checking __cpp_lib_concepts for the C++20 official version appears to work.
Pick-to: 6.3 6.2
Change-Id: I8c31cd64de24c03b3a3f37cb393bb2f9b55a834d
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Remove Integrity and Android specific code that explicitly adds
test data to the resource files. qt_internal_add_test functions
implicitly adds test data to resources for Android and Integrity
platforms by default.
Change-Id: Ia1d58755b47442e1953462e38606f70fec262368
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
The value of __cplusplus has nothing to do with whether the library
implements wg21.link/P1115 (libstdc++ even before C++20) or not
(libc++, even in C++20).
Use the idiomatic check (#if defined(foo) && foo >= x) instead,
fixing the Android build.
Pick-to: 6.3 6.2
Change-Id: I11bcefe455a1f13865c15d4beecbd3fe32115328
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
qt_internal_undefine_global_definition disables an internal global
definition that is defined by the qt_internal_add_global_definition
function for a specific target.
Remove the ability to set the custom "undefine" flag for the
definitions since it's hard to control it using the introduced
function.
Pick-to: 6.2 6.3
Task-number: QTBUG-100334
Change-Id: Ic1637d97aa51bbdd06c5b191c57a941aa208d4dc
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
The code was trying to avoid a detach in the case no element needed to
be removed, by first running find_if() on const_iterators, and then,
after converting its result to (mutable) iterators, start the
remove_if() algorithm where find_if() left off.
But this applies the predicate to the element found by find_if() (if
any) _twice_: first just before we exit the first find_if() and then
just as we enter remove_if(), which will start by running find_if()
again, with the result of the initial find_if as 'first'.
Apart from being needlessly inefficient, this violates the
specification of Uniform Erasure, which defines sequential erase_if()
as being equivalent to remove_if() + container erase(), with the
former being specified to apply the predicate exactly once per
element.
Fix by writing the remove_if() part by hand.
Instead of doing the dance with the loop invariant documentation
twice, simply implement erase() via erase_if() (complicated a bit by
the weird passing of predicates by lvalue reference instead of by
value, as would be idiomatic). This exposes users to:
[ChangeLog][QtCore][Potentially Source-Incompatible Changes] A fix in
the implementation of the erase-like algorithms of sequential Qt
container may re-enable signed/unsigned comparison warnings previously
suppressed by having occurred in std library code. To fix, cast the
value to look for such that it has the same signedness as the
container's elements.
... but the issue would be the same had we inlined std::remove()
instead of passing a lambda to sequential_erase_if(), so it's nothing
we can, nor should, work around.
[ChangeLog][QtCore][Containers] Fixed a bug in the implementation of
most sequential Qt container's erase-like algorithms (member
removeAll()/removeIf() and free erase()/erase_if()) where the equality
operator or the predicate, respectively, was applied to the first
matching element twice. Each element is now tested exactly once.
Pick-to: 6.3 6.2
Change-Id: Ib6d24b01b40866c125406f1cd6042d4cd083ea0d
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Restore the 'QT_NO_JAVA_STYLE_ITERATORS' and
'QT_NO_NARROWING_CONVERSIONS_IN_CONNECT' definitions for Qt
targets.
Add the function that adds global definitions for Qt targets according
to the provided scope and the target property-based switch to disable
the definition for a specific target.
Pick-to: 6.2 6.3
Task-number: QTBUG-100295
Change-Id: I28697e81f9aabc45c48d79aae1e5caea141e04e1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Add a level of indirection via void_t such that
struct is_transparent {};
works, and not just
using is_transparent = <unspecified>;
Pick-to: 6.3
Change-Id: I3ca2af6a07e6989dc95abc10fb2d0078a5269e5b
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>