summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools
Commit message (Collapse)AuthorAgeFilesLines
* QVarLengthArray: fix off-by-size() bug in growBy()Marc Mutz14 days1-0/+13
| | | | | | | | | | | | | | | | | 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 26b227e128475da3f88a6b34921a08994bf71cf4. 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>
* QVarLengthArray: cope with vector<unique_ptr>'s copyabilityMarc Mutz2023-01-161-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | 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 a00a1d8806cfbf17e04b88d1b4ff4a9cf5b6294a. 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>
* tst_QAlgorithms: don't use random numbers in the test row namesThiago Macieira2023-01-111-17/+25
| | | | | | | | | | | | | | | | | | 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>
* QTypeInfo: remove further usages of isPointer / isIntegralGiuseppe D'Angelo2022-12-302-3/+3
| | | | | | | In preparation to their deprecation / removal. Change-Id: Ia073a9f7caabbc06063a1e416b23cdb12788b283 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QOffsetStringArray: add contains() methodMarc Mutz2022-12-091-0/+11
| | | | | | | ... use it in QNetworkReplyWasmImpl. Change-Id: I648f02fcafda43af7ed9771cc1c7e2e2a6d38504 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* ContainerApiSymmetry: verify Qt containers member erase returns iteratorAhmad Samir2022-12-021-0/+79
| | | | | | | | | | 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>
* tst_QMap: remove unused std::as_const cloneMarc Mutz2022-11-181-6/+0
| | | | | | | | Amends d273076b4474bb473d90e996960c4c773745761a. Pick-to: 6.4 6.2 Change-Id: Icfff438223ed10756f15e25ea52cccdf93dd47a2 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* Port from container::count() and length() to size() - V5Marc Mutz2022-11-039-112/+115
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* QHash: tame HasQHashSingleArgOverload ODR violationsGiuseppe D'Angelo2022-11-011-0/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* tst_QSet: fix flakiness after we removed the fixed, non-zero seedThiago Macieira2022-10-181-11/+21
| | | | | | | | | | | | | | 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 b057e32dc455d81f9378d6bd0c58888a7eddd155 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>
* tst_QRect::containsPointF_data(): remove duplicate data rowEdward Welbourne2022-10-181-2/+0
| | | | | | | | | | | 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>
* tst_QCryptographicHash: avoid duplicate data tagsEdward Welbourne2022-10-181-1/+1
| | | | | | | | | 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>
* tst_QBitArray: remove duplicate data rowsEdward Welbourne2022-10-181-2/+0
| | | | | | | | 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>
* tst_Q{BitArray,ContiguousCache}: check not only count(), but size(), tooMarc Mutz2022-10-172-0/+3
| | | | | | | | 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>
* tst_QAlgorithms: fix misleading indent in data tableEdward Welbourne2022-10-171-8/+11
| | | | | | | | | | 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>
* Clean up tst_QAlgorithms::count{Trail,Lead}ing_data_impl()Edward Welbourne2022-10-171-12/+15
| | | | | | | | | | | | | | | 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>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-112-5/+5
| | | | | | | | | | | | | | | | 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>
* Port from container.count()/length() to size()Marc Mutz2022-10-0411-128/+128
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is semantic patch using ClangTidyTransformator: auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o) makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'. <classes> are: // sequential: "QByteArray", "QList", "QQueue", "QStack", "QString", "QVarLengthArray", "QVector", // associative: "QHash", "QMultiHash", "QMap", "QMultiMap", "QSet", // Qt has no QMultiSet Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QTaggedPointer: disable operator= with an empty initializer listGiuseppe D'Angelo2022-09-291-0/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* tst_QHash: Fix outdated rehash testMårten Nordheim2022-09-221-2/+2
| | | | | | | | | | 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>
* Disable bad tests relying on wrong behaviorAllan Sandfeld Jensen2022-09-151-20/+10
| | | | | | | | | | | 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>
* QCryptographicHash: Add getter for algorithm()Linus Jahn2022-09-121-0/+2
| | | | | | | | | | | | 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>
* Make QCryptographicHash move constructibleLinus Jahn2022-09-121-0/+37
| | | | | | | | | | | | 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>
* Move QMacAutoReleasePool from qglobal.h to qcore_mac_p.hSona Kurazyan2022-09-012-0/+3
| | | | | | | | 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>
* tst_QMap: avoid tripping MSVC debug-mode iterator assertionsThiago Macieira2022-08-281-1/+6
| | | | | | | | | 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>
* tst_qscopedpointer: port away from deprecated APIsIvan Solovev2022-08-271-20/+48
| | | | | | | | | | | | | | | | | 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>
* tst_qmap: port away from deprecated APIsIvan Solovev2022-08-271-70/+110
| | | | | | | | | | | | | | 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>
* Port tests away from using q{Set}GlobalQHashSeedIvan Solovev2022-08-263-7/+28
| | | | | | | | 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>
* Change the license of all CMakeLists.txt and *.cmake files to BSDLucie Gérard2022-08-2346-46/+46
| | | | | | | Task-number: QTBUG-105718 Change-Id: I5d3ef70a31235868b9be6cb479b7621bf2a8ba39 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Tests: remove #define COMMAThiago Macieira2022-08-091-7/+5
| | | | | | | | | | 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>
* Add license headers to cmake filesLucie Gérard2022-08-0346-0/+138
| | | | | | | | | | | | 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>
* CMake: Don't use PUBLIC_LIBRARIES for tests and test helpersAlexandru Croitor2022-07-2812-12/+12
| | | | | Change-Id: I9b7404e1d3a78fe0726ec0f5ce1461f6c209e90d Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
* Increase timeout of slow test for ASAN-enabled buildDimitrios Apostolou2022-06-151-0/+4
| | | | | Change-Id: I47b6e7e1462c1af7d41677bfe7bb0f78430f72d1 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Long live QAtomicScopedValueRollback (private API)!Marc Mutz2022-05-315-3/+169
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Use SPDX license identifiersLucie Gérard2022-05-1654-1465/+115
| | | | | | | | | | | | | 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>
* QVarLengthArray: add missing (size, value) ctorMarc Mutz2022-04-131-0/+12
| | | | | | | | | | | Extend the corresponding test in tst_containerapisymmetry. [ChangeLog][QtCore][QVarLengthArray] Added (size, value) constructor. Fixes: QTBUG-102469 Change-Id: I4802eebe6ba1a6835e4d6f41e1d3db2a0d7c7894 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Replace uses of _qs with _s in testsSona Kurazyan2022-04-071-1/+3
| | | | | | Task-number: QTBUG-101408 Change-Id: If092a68828a1e8056259cf90d035d9a87989244b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Q[Multi]Hash: fix squeeze()Ivan Solovev2022-04-061-1/+94
| | | | | | | | | | | | | | | | | | | 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 8a984ab772dd194e39094e728b869e65912912a7 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>
* Q[Multi]Hash::reserve(): do nothing if desired size is less than currentIvan Solovev2022-04-061-0/+31
| | | | | | | | | | | | | | | | 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>
* QByteArray/QVarLengthArray: add missing resize(n, v) overloadsMarc Mutz2022-04-061-0/+23
| | | | | | | | | | | | | | | | | | 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>
* Fix compiler warnings in testsVolker Hilsheimer2022-03-241-1/+1
| | | | | | | | Don't mix unsigned and signed types in comparisons. Pick-to: 6.3 Change-Id: Ia4ba9c114177425a21cadc8cafe8179928315a5d Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QRect: add toRectF()Marc Mutz2022-03-191-1/+38
| | | | | | | | | | For symmetry with QRectF::toRect(). [ChangeLog][QtCore][QRect] Added toRectF(). Fixes: QTBUG-73160 Change-Id: If2bda64b8fe4bc113191dda927e9bb86ebcb4c69 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLine/QMargins: add toLineF/toMarginsF()Marc Mutz2022-03-192-2/+71
| | | | | | | | | | | | | For symmetry with QLineF::toLine(). [ChangeLog][QtCore][QLine] Added toLineF(). [ChangeLog][QtCore][QMargins] Added toMarginsF(). Task-number: QTBUG-73160 Change-Id: I69051cdd2fe4a3c0a000ab86e363a2918a7aea7c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QSize/QPoint: add toSizeF/toPointF()Marc Mutz2022-03-192-2/+60
| | | | | | | | | | | | | For symmetry with QSizeF::toSize(). [ChangeLog][QtCore][QSize] Added toSizeF(). [ChangeLog][QtCore][QPoint] Added toPointF(). Task-number: QTBUG-73160 Change-Id: I65b088b4f7365ab671ef2f0c75821b707f5ac26d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Tests: Do not depend on transitive includesFabian Kosmale2022-03-175-0/+6
| | | | | Change-Id: Ibc6a948480a904913a5427e6408d4d296784fb4f Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QFlatMap: make insertion STL-compatibleMarc Mutz2022-03-161-16/+3
| | | | | | | | | | | | | | | | | | | | | | 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>
* tst_qflatmap: fix -Wunused-local-typedef (Clang)Marc Mutz2022-03-111-1/+1
| | | | | | | | | | | False Positive, of course, since it's used in dependent callee transparent_impl(). Amends 58e8ae5605abefd0f579586a890dc13fb381b2a3. Pick-to: 6.3 Change-Id: I7520fb7cf6bce28a5fd9381783ba349119309132 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QWeakPointer: befriend other QWeakPointersThiago Macieira2022-03-041-3/+52
| | | | | | | | | | Commit c677b3b8afcdc1d7b57353826cc01f378cd25e99 added move constructors, which introduced the issue. Pick-to: 6.2 6.3 Fixes: QTBUG-100795 Change-Id: I74249c52dc02478ba93cfffd16d2c879b923e352 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
* Associative containers: add a way to obtain a key/value rangeGiuseppe D'Angelo2022-03-041-0/+131
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* QFlatMap: add remove_ifMarc Mutz2022-03-031-0/+87
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>