summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qcompare.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Long live \constraints!Marc Mutz2025-02-281-30/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We have divergence in the way we document function, operator and constructor constraints. About half use \note, while the other doesn't. Some say "if and only if" while others say just "participates only if". So add a qdoc macro, \constraints, to semantically mark up these constraints. It expands to a section titled `Constraints`, and uses a predefined sentence (prefix) for constraints. Documentation for constraints is moved to the end of the comment blocks to separate them from the rest of the text. Apply them to all the standard-ish constraint documentation blocks (grepped for "participate"). I didn't look for other, one-off, ways documentation authors may have documented constraints, but I'm also not aware of any. Re-wrap lines only if the result fits into a single line. As a drive-by, drop additional "if"s, as in "only if X and -if- Y" to make the texts work with the `Constraints` section. Fixes: QTBUG-106871 Pick-to: 6.9 6.8 6.5 Change-Id: I18c2f9f734474017264e49165389f8c9c7f34030 Reviewed-by: Kai Köhne <kai.koehne@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Add QtOrderingPrivate::lexicographicalCompareThreeWayIvan Solovev2024-11-271-0/+36
| | | | | | | | | | | | | | | | | | | | | | | This function should behave similarly to std::lexicographical_compare_three_way, but be available in C++17. It is required at least to properly implement the compareThreeWay() helper function for Qt container types. The function requires that the contained types of the compared ranges provide a compareThreeWay() helper function. Similarly to std implementation, this patch also adds an overload that takes a custom comparator object. For now the functions are added in a private namespace, because they are only required to implement relational operators on Qt containers. We might want to expose them as public API later, if needed. Task-number: QTBUG-127095 Task-number: QTBUG-120305 Change-Id: I5b29129905b2e801ae7e470c96a7ef71e7b210d6 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Long live Q_DECLARE_ORDEREDMarc Mutz2024-09-091-0/+54
| | | | | | | | | | | | | | | This is a version of the comparison helper macro for the cases where the ordering strength depends on the template arguments (think std::pair<double, int> vs std::pair<int, int>). This patch also adds the _LITERAL_TYPE and _NON_NOEXCEPT overloads of the macros that generate the constexpr and noexpect(false) relational operators respectively. Done-with: Ivan Solovev <ivan.solovev@qt.io> Task-number: QTBUG-127095 Change-Id: I368cf2ff385213be7d2c7477a8346e83ce841b91 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Comparison helper macros: support variable number of attributesIvan Solovev2024-08-131-12/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Comparison macros already had the possibility to specify attributes. These attributes were added in front of each of the generated comparison operators. The original usecase was to allow QT_ASCII_CAST_WARN macro before each of the generated operators, which was needed e.g. for QString vs QByteArray comparison [0]. However, further work on applying the macros within QtCore revealed that the same macro parameter can be used if the operators need to be template functions [1]. This usecase was, however, limited to templates with a single type and no constraints. In order to support templates with more than one type, as well as complex template constraints, we need to convert the comparison helper macros into variadic macros, and make Attributes a variable parameter. This allows us to specify more complex templates, as well as template constraints as attributes. Due to the implementation of QT_OVERLOADED_MACRO(), which supports maximum of 9 arguments, we can support up to 7 comma-separated arguments for the attributes (because two marco arguments are used for the left and right hand side types of the comparison). We need to explicitly define all nine overloads of the macro, though. And because of MSVC incorrectly expanding __VA_ARGS__ as one(!) argument, we need to use QT_VA_ARGS_EXPAND in these definitions. [0]: 42b6fdfb523f47ba711138bb299d97823e7c64d2 [1]: 890c270b9b27de5075bda668dbe8117649673b05 Task-number: QTBUG-127095 Change-Id: I90f3c53f7135562989eabefa29e05d47264ca089 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Rework comparison helper macros to get rid of conditional noexceptIvan Solovev2024-07-161-0/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The conditional noexcept in comparison operators is known to cause problems in various cases. For example, we had a problem in QBAV, where gcc and clang tried to expand conditional noexcept before the class was complete, and, as a result, discarded some of the QBAV constructors (see fff6562f8c074d75bda8b80f844dc63c6f2e64d5 for a more detailed explanation). Other problem is related to the GHS compiler which tries to compile the noexcept specification and provides a hard error instead of SFINAE'ing out in case of failure (see e1f45ad8187947e243c8247c5cbac2d884d68d55 or 0ac0b412c754e53d167716f207be9d76a7fe16be as examples). This patch reworks the macros to get rid of the conditional noexcept. Instead, it demands that all operators are noexcept by default, and adds another set of helper macros that can be used if it's not possible to make the relational operators noexcept. The new macros end with the _NON_NOEXCEPT suffix. The patch also adds static_assert() to the generated operators to verify that the proper macros are used. However, some platforms (e.g. QNX and Integrity) fail to handle conditional noexcept on lambdas, and so we have to use yet another macro to generate the checks only on platforms that handle them properly. This patch also applies the new approach to qtbase, adding noexcept where possible, and falling back to the _NON_NOEXCEPT macros otherwise. As a drive-by: fix the macro implementation to use QtOrderingPrivate::reversed() instead of manually reimplementing it. I decided to pick the patch to 6.8, because it allows to fix some questionable APIs (see QBAV story above). Pick-to: 6.8 Change-Id: I72f56778acb469f18b578b3418c0c41b4f6d62e7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Update Qt::compareThreeWay(Qt::totally_ordered_wrapper) overloads to take ↵Ivan Solovev2024-06-071-3/+12
| | | | | | | | | | | | | | | | | | | | | | | compatible pointer types Unlike the old Qt::compareThreeWay() overload for raw pointers, the new overloads for the Qt::totally_ordered_wrapper didn't allow to compare wrappers of different (but compatible) pointer types (base vs derived). This patch fixes it. Ideally the constraints on operators in Qt::totally_ordered_wrapper should use std::common_type_t, but we hit a bug in VxWorks that prevents us from using it, so simply demand that the types are convertible pointers. For now that should be enough, considering that Qt::totally_ordered_wrapper only expects pointers as wrapped types. Found in API Review. Pick-to: 6.8 Change-Id: I9f7184468bea3e1f2944ca5347f0b79eded2f4d3 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Deprecate Qt::compareThreeWay() overload for pointersIvan Solovev2024-06-071-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | compareThreeWay() was supposed to be an operator<=>(), but for C++17. The idea was that at some point when we unconditionally demand C++20, people could just replace all the usages of compareThreeWay() with operator<=>(). However, the Qt::compareThreeWay() overload for pointers is different from the operator<=>() for pointers, because it is actually using std::less{} or std::compare_three_way{} to do the comparison, thus avoiding an UB. This is not bad as such, but can potentially lead to UB when mass-replacing all compareThreeWay() calls with operator<=>(). To avoid this problem, deprecate the overload, and suggest to use the Qt::totally_ordered_wrapper together with the respective overload instead. Found in API Review. [ChangeLog][QtCore][QtCompare] Deprecate Qt::compareThreeWay() overload for pointers. Pick-to: 6.8 Change-Id: I9c57871145dc3cb9656d6006db88b48a1553bef4 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Add Qt::compareThreeWay() overloads for Qt::totally_ordered_wrapperIvan Solovev2024-06-071-0/+71
| | | | | | | | | | | | | | | | | | | | | Provide the overloads as free functions in Qt namespace instead of making them hidden friends of the Qt::totally_ordered_wrapper class, because they should replace the to-be-deprecated overloads of Qt::compareThreeWay() for raw pointers, so they should be easily discoverable. Also, we treat Qt::compareThreeWay() as a C++17 equivalent of operator<=>(), so we need to have an overload for pointers (even if it takes only the wrapped pointers). Found in API Review. [ChangeLog][QtCore][QtCompare] Added Qt::compareThreeWay() overloads for Qt::totally_ordered_wrapper. These overloads do the comparison using strict total ordering. Pick-to: 6.8 Change-Id: I2b5bc542c546330ca78c6284188c8167136a849e Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Docs: fix include header for Qt::*_ordering typesIvan Solovev2024-05-241-0/+3
| | | | | | | | | | | | | | | As the classes do not use the common naming pattern, qdoc suggested some weird non-existend includes when generating the docs for these classes. Explicitly use the \inheaderfile qdoc command to point to a proper include. Amends bdd41f491c0f85ae0897a1c7372c5ecda62a5aab. Pick-to: 6.7 Change-Id: Ia721658df38f1006fdc2fa1de1fab7eb381ceb0b Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Document Qt::totally_ordered_wrapperIvan Solovev2024-05-241-0/+53
| | | | | Change-Id: I9249ee6473b68c5e3a9c328ae4d61b7cd83cb505 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Change license in files to avoid LGPL and non-LGPL license mixLucie Gérard2024-02-201-1/+1
| | | | | | | | | | | | | | | | | | | | According to QUIP-18 [1], all module files should be LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only or LicenseRef-Qt-Commercial OR GPL-3.0-only LGPD and non-LGPL licenses should not be mixed in a given directory. The files in this patch are the only ones in their directory with non-LGPL license. The license is changed to that of the other module files in the same directory. [1]: https://contribute.qt-project.org/quips/18 Pick-to: 6.7 Task-number: QTBUG-121787 Change-Id: Id58248a6f60438e01e77e9448f07e3057d173260 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
* Comparison helper macros: add an Attributes parameterIvan Solovev2024-02-201-0/+23
| | | | | | | | | | | | | Some of relational operators in Qt are marked with QT_ASCII_CAST_WARN (see e.g. String, QLatin1StringView). If we want to convert these operators to the new comparison helper macros, we need a way to preserve this attribute. My tests show that simply adding the attribute to the helper comparesEqual() and compareThreeWay() functions does not work, so we need to explicitly add it to each of the generated operators. Change-Id: I2940a70fe191326e8a2ebfb05b8da6e0f21a845c Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Improve documentation of Qt ordering typesIvan Solovev2024-01-181-46/+40
| | | | | | | | | | Apply some documentation improvements that were suggested before FF. Task-number: QTBUG-119433 Pick-to: 6.7 Change-Id: I9b1d83c69821e25ae4cd8db0cbf3fa6d6330a6dc Reviewed-by: Dennis Oberst <dennis.oberst@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Doc: Fix documentation issues for Qt CoreTopi Reinio2023-12-191-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Fix template arguments in \fn signatures for Qt::compareThreeWay() functions. * Fix template arguments in \fn signatures for QDebug::operator<<() functions. * Fix \sa links to specific overloads of QSpan functions. * Fix \sa links to specific overloads of QFileInfo::fileTime(). * Remove references to 'Custom Type Example' (example has been removed). * Fix linking to 'JSON Save Game' example. * Fix references to 'Queued Custom Type' example. * Fix linking to QCryptographicHash::Algorithm. * Fix linking to Qt Qml module. * Fix undocumented parameters in qHypot(). Pick-to: 6.7 Change-Id: If9eb9978a14e147f003672a682972b319454c311 Reviewed-by: Luca Di Sera <luca.disera@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QPartialOrdering: add lower-case flags for std/Qt:: compatibilityMarc Mutz2023-12-071-12/+40
| | | | | | | | | | | | The misspelt flags (Less, etc) make it hard to use QPartialOrdering interchangably with Qt or std ordering types, e.g. in generic code. [ChangeLog][QtCore][QPartialOrdering] Added a set of lower-case flags (::less, ::greater, etc) to improve source-compatibility with {Qt,std}::partial_ordering. Change-Id: I160600c01c4a2ab72c7b217a306d08045e363578 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Long live qCompareThreeWay()Ivan Solovev2023-12-071-0/+59
| | | | | | | | | | | | | | | | | | | | | | | | | qCompareThreeWay() is a top-level wrapper around the helper three-way comparison methods, which is mostly convenient for generic client code. When implementing compareThreeWay() for Qt types, we normally provide the implementation only for (LeftType, RightType) pair, but not the reversed one. However, it is expected that qCompareThreeWay() would be available for both combinations, because the reversed result can be easily calculated. Solve it by providing a helper hasCompareThreeWay<LT, RT> variable and branching the implementation based on its value. The noexcept check is inspired by the old implementation of qSwap(). [ChangeLog][QtCore] Added qCompareThreeWay() as a public API for three-way comparison. Task-number: QTBUG-104113 Change-Id: I6f24494d968c336f3dcdf620004b4190769cbdb2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QPartialOrdering: add missing \since to is_eq etcMarc Mutz2023-12-051-0/+1
| | | | | Change-Id: I8d04e75805ed503f432b5ea117bd2b885cb57e38 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Doc: Fix \fn template arguments for Qt CoreLuca Di Sera2023-11-301-6/+6
| | | | | | | | | Upcoming changes to QDoc require accurate definition for template arguments in \fn commands. Task-number: QTBUG-118080 Change-Id: I64d50919bc6ffab61ef5ead553d1da99d63a9f21 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* Implement helper Qt::compareThreeWay() function for built-in typesIvan Solovev2023-11-281-0/+151
| | | | | | | | | | | | | | | | | | | | | | | | | The helper function RetType compareThreeWay(const T &left, const T &right) noexcept; is used for C++20-comparison macros. Normally it's the user's responsibility to provide this function as a hidden friend of the class which uses the comparison helper macros. For built-in types we provide the implementation inside the Qt namespace. We have to use custom IsIntegralType trait because libstdc++ only treats __{u}int128_t types as integral when compiling in -std=gnu++XX mode, and we compile Qt in -std=c++XX mode. This patch provides the implementations only for compareThreeWay() overloads, because there is no need to implement comparesEqual() for built-in types. It would just be equivalent to calling operator==(), so the user can do it directly. Task-number: QTBUG-104113 Change-Id: I7b3f395458e1ee4c64f442ad48bbf4fec4c19c52 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Implement compare helper macrosIvan Solovev2023-11-281-0/+336
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These macros should unwrap into a proper set of equality and ordering operators, depending on the C++ standard being used. For C++17, all 6 operators (==, !=, <, >, <=, >=) are overloaded, while for C++20 only the overloads for opeartor==() and operator<=>() are provided. The macros are documented as internal for now. The macros rely on two helper functions: bool comparesEqual(LeftType lhs, RightType rhs); ReturnType compareThreeWay(LeftType lhs, RightType rhs); The comparesEqual() helper function is used to implement operator==() and operator!=(). The compareThreeWay() helper function is used to implement the four relational operators in C++17, or operator<=>() in C++20. ReturnType must be one of Qt::{partial,weak,strong}_ordering. When possible, the functions should also be declared constexpr and noexcept. It's the user's responsibility to provide the functions before using the macros. Implement a test case which applies the new macros to the dummy classes, and uses the new helper function to verify the comparison results. The MSVC compiler before version 19.36 has a bug, where it fails to correctly generate reverse opeerators in C++20 mode. Introduce a new Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY definition for such compiler versions, and use it to manually generate reversed operators when needed. Task-number: QTBUG-104113 Change-Id: Idc19d55df011fd616ff654f35a964e831b8ab93b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Qt::*_ordering: use std::bit_cast when converting to std::_orderingMarc Mutz2023-11-271-3/+0
| | | | | | | | | | | | | GCC, in particular, doesn't understand that the types are fundamentally the same unless you compile with -O3, so help the compiler by using bit_cast when it is available. GCC now produces the same code at -O2 as previously only at -O3. Still no tail-calls, though. Task-number: QTBUG-118913 Change-Id: Ib1241a98f1de49c59a2e16b7d1f5cf813db4edf7 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Make Qt::partial_ordering binary-compatible to std::partial_orderingMarc Mutz2023-11-271-0/+768
In particular, match the value of ::unordered to each std library implementation. Legal disclaimer: The values were provided to this author in a comment on QTBUG-118913. This author hereby confirms he didn't look at any of the implementations himself. The stdlib detection macros are taken from existing code in qcompilerdetection.h. I didn't succeed in googling a corresponding marker for MSSTL, and I didn't look at the implementation or Boost.Config to find one, so this patch just assumes MSSTL as a fall-back, which is probably wrong, since we may still have Dinkumware and RougeWave STLs to deal with on embedded platforms. Add tests to ensure the values are the same on all platforms. To maximize coverage, rename qcompare.qdoc to qcompare.cpp and add a bunch of compile-time tests there. These depend in part on bit_cast, which we cannot depend on, so tst_qcompare contains the same tests using memcpy. Fixes: QTBUG-118913 Change-Id: I46c922c8e3ea37d7c01a71361c7a689340f9047d Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>