diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-02-15 00:11:22 +0100 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-06-10 16:49:08 +0200 |
commit | 8e98a161e993c6636d217276a0f2373d642ff050 (patch) | |
tree | 23adce823bfab9795cf7b775d35f14be7baedc10 | |
parent | ce5931aaf2c9698925366e787d08747a1c60c378 (diff) |
Long live std::pair!
Make QPair an alias for std::pair, and qMakePair just a forwarder
towards std::make_pair.
Why? Fundamentally to ditch a bunch of NIH code; gain for free
structured bindings, std::tuple and std::reference_wrapper
compatibility, and so on.
Breakages:
* Some that code manually forward declares QPair.
We don't care about it (<QContainerFwd> is the proper way).
* Some code that overloads on std::pair and QPair. Luckily
it's mostly centralized: debug, metatypes, testing macros.
Just remove the QPair overload.
* Usages of qMakePair forcing the template type parameters.
There are a handful of these in qtbase, but only one was actually
broken.
* std::pair is NOT (and will never likely be) trivially copiable.
This is agreed to be a mistake done by practically all implementations
in C++11, can can't be fixed without breaking ABI.
Some code using QPair assuming it's trivially copiable may break;
exactly one occurrence was in qtbase.
* QMetaType logic extracts the type names in two different ways,
one by looking at the source code string (e.g. extracted by moc)
and one via some ad-hoc reflection in C++. We need to make
"QPair" (as spelled in the source code) be the same as "std::pair"
(gathered via reflection, which will see through the alias)
when compared. The way it's already done e.g. for QList is
by actually replacing the moc-extracted name with the name
of the actual type used in C++; do the same here.
On libc++, std::pair is actually in an inline namespace --
i.e. std::__1::pair; the reflection will extract and store
"std::__1::pair" so we need an ad-hoc fix to QMetaType.
[ChangeLog][QtCore][QPair] QPair is now an alias to std::pair,
and does not exist as a class in Qt any more. This may break
code such as functions overloaded for both QPair and std::pair.
Usually, the overload taking a QPair can be safely discarded,
leaving only the one taking a std::pair. QPair API has not changed,
and qMakePair is still available for compatibility (although
new code is encouraged to use std::pair and std::make_pair
directly instead).
Change-Id: I7725c751bf23946cde577b1406e86a336c0a3dcf
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
28 files changed, 93 insertions, 500 deletions
diff --git a/src/corelib/doc/snippets/code/doc_src_qpair.cpp b/src/corelib/doc/snippets/code/doc_src_qpair.cpp deleted file mode 100644 index e62f91830c..0000000000 --- a/src/corelib/doc/snippets/code/doc_src_qpair.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <qmath.h> - -//! [0] -QPair<QString, double> pair; -//! [0] - - -//! [1] -pair.first = "pi"; -pair.second = M_PI; -//! [1] - -//! [struct] -struct Variable { - QString name; - double value; -}; -Variable v; -v.name = "pi"; -v.value = M_PI; -//! [struct] - -//! [2] -QList<QPair<int, double> > list; -list.append(qMakePair(66, M_PI)); -//! [2] diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc index 537bd8c884..d73c9dd07b 100644 --- a/src/corelib/doc/src/containers.qdoc +++ b/src/corelib/doc/src/containers.qdoc @@ -608,8 +608,6 @@ \li QContiguousCache<T> provides an efficient way of caching data that is typically accessed in a contiguous way. - - \li QPair<T1, T2> stores a pair of elements. \endlist Additional non-template types that compete with Qt's template diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 723bb478ad..22ba3879f4 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -45,7 +45,6 @@ #include <QtCore/qhash.h> #include <QtCore/qlist.h> #include <QtCore/qmap.h> -#include <QtCore/qpair.h> #include <QtCore/qtextstream.h> #include <QtCore/qstring.h> #include <QtCore/qvector.h> @@ -319,15 +318,6 @@ inline QDebug operator<<(QDebug debug, const QMultiHash<Key, T> &hash) } template <class T1, class T2> -inline QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair) -{ - const bool oldSetting = debug.autoInsertSpaces(); - debug.nospace() << "QPair(" << pair.first << ',' << pair.second << ')'; - debug.setAutoInsertSpaces(oldSetting); - return debug.maybeSpace(); -} - -template <class T1, class T2> inline QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair) { const QDebugStateSaver saver(debug); diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index d8b547c8e2..d964c16915 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -240,8 +240,7 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId(); #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \ F(QHash, class) \ - F(QMap, class) \ - F(QPair, struct) + F(QMap, class) #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \ F(QSharedPointer) \ @@ -1392,15 +1391,6 @@ template<typename From> struct QPairVariantInterfaceConvertFunctor; template<typename T, typename U> -struct QPairVariantInterfaceConvertFunctor<QPair<T, U> > -{ - QPairVariantInterfaceImpl operator()(const QPair<T, U>& f) const - { - return QPairVariantInterfaceImpl(&f); - } -}; - -template<typename T, typename U> struct QPairVariantInterfaceConvertFunctor<std::pair<T, U> > { QPairVariantInterfaceImpl operator()(const std::pair<T, U>& f) const @@ -1670,8 +1660,6 @@ namespace QtPrivate } }; template<typename T, typename U> - struct IsPair<QPair<T, U> > : IsMetaTypePair<QPair<T, U> > {}; - template<typename T, typename U> struct IsPair<std::pair<T, U> > : IsMetaTypePair<std::pair<T, U> > {}; template<typename T> @@ -2209,7 +2197,6 @@ Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QHash) Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(QMap) Q_DECLARE_ASSOCIATIVE_CONTAINER_METATYPE(std::map) -Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair) Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::pair) #define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \ @@ -2532,6 +2519,16 @@ public: // Replace QList by QVector appendStr("QVector"); } + + if (skipToken(begin, end, "QPair")) { + // replace QPair by std::pair +#ifdef _LIBCPP_VERSION + appendStr("std::" QT_STRINGIFY(_LIBCPP_ABI_NAMESPACE) "::pair"); +#else + appendStr("std::pair"); +#endif + } + if (!hasMiddleConst) { // Normalize the integer types int numLong = 0; diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index 3026e554bf..316a164c6d 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -1119,6 +1119,16 @@ int QDataStream::readRawData(char *s, int len) return readBlock(s, len); } +/*! \fn template <class T1, class T2> QDataStream &operator>>(QDataStream &in, std::pair<T1, T2> &pair) + \since 6.0 + \relates QDataStream + + Reads a pair from stream \a in into \a pair. + + This function requires the T1 and T2 types to implement \c operator>>(). + + \sa {Serializing Qt Data Types} +*/ /***************************************************************************** QDataStream write functions @@ -1446,6 +1456,18 @@ int QDataStream::skipRawData(int len) return skipResult; } +/*! + \fn template <class T1, class T2> QDataStream &operator<<(QDataStream &out, const std::pair<T1, T2> &pair) + \since 6.0 + \relates QDataStream + + Writes the pair \a pair to stream \a out. + + This function requires the T1 and T2 types to implement \c operator<<(). + + \sa {Serializing Qt Data Types} +*/ + QT_END_NAMESPACE #endif // QT_NO_DATASTREAM diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index 4568ba3a84..c11d6803ac 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -480,14 +480,14 @@ inline QDataStream &operator<<(QDataStream &s, const QMultiMap<Key, T> &map) #ifndef QT_NO_DATASTREAM template <class T1, class T2> -inline QDataStream& operator>>(QDataStream& s, QPair<T1, T2>& p) +inline QDataStream& operator>>(QDataStream& s, std::pair<T1, T2> &p) { s >> p.first >> p.second; return s; } template <class T1, class T2> -inline QDataStream& operator<<(QDataStream& s, const QPair<T1, T2>& p) +inline QDataStream& operator<<(QDataStream& s, const std::pair<T1, T2> &p) { s << p.first << p.second; return s; diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h index bdf9e0dcc0..fd4701a8b1 100644 --- a/src/corelib/tools/qcontainerfwd.h +++ b/src/corelib/tools/qcontainerfwd.h @@ -50,7 +50,8 @@ template <class Key, class T> class QHash; template <class Key, class T> class QMap; template <class Key, class T> class QMultiHash; template <class Key, class T> class QMultiMap; -template <class T1, class T2> struct QPair; +template <typename T1, typename T2> +using QPair = std::pair<T1, T2>; template <class T> class QQueue; template <class T> class QSet; template <class T> class QStack; diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index 5742540061..38e799e78b 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -252,15 +252,6 @@ inline size_t qHashRangeCommutative(InputIterator first, InputIterator last, siz return std::accumulate(first, last, seed, QtPrivate::QHashCombineCommutative()); } -template <typename T1, typename T2> inline size_t qHash(const QPair<T1, T2> &key, size_t seed = 0) - noexcept(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) -{ - QtPrivate::QHashCombine hash; - seed = hash(seed, key.first); - seed = hash(seed, key.second); - return seed; -} - template <typename T1, typename T2> inline size_t qHash(const std::pair<T1, T2> &key, size_t seed = 0) noexcept(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) { diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h index 9ebf88bc8f..6cb7fc5079 100644 --- a/src/corelib/tools/qpair.h +++ b/src/corelib/tools/qpair.h @@ -44,115 +44,22 @@ QT_BEGIN_NAMESPACE - -template <class T1, class T2> -struct QPair -{ - typedef T1 first_type; - typedef T2 second_type; - - Q_DECL_CONSTEXPR QPair() - noexcept((std::is_nothrow_default_constructible<T1>::value && - std::is_nothrow_default_constructible<T2>::value)) - : first(), second() {} - Q_DECL_CONSTEXPR QPair(const T1 &t1, const T2 &t2) - noexcept((std::is_nothrow_copy_constructible<T1>::value && - std::is_nothrow_copy_constructible<T2>::value)) - : first(t1), second(t2) {} - // compiler-generated copy/move ctor/assignment operators are fine! - - template <typename TT1, typename TT2> - Q_DECL_CONSTEXPR QPair(const QPair<TT1, TT2> &p) - noexcept((std::is_nothrow_constructible<T1, TT1&>::value && - std::is_nothrow_constructible<T2, TT2&>::value)) - : first(p.first), second(p.second) {} - template <typename TT1, typename TT2> - Q_DECL_RELAXED_CONSTEXPR QPair &operator=(const QPair<TT1, TT2> &p) - noexcept((std::is_nothrow_assignable<T1, TT1&>::value && - std::is_nothrow_assignable<T2, TT2&>::value)) - { first = p.first; second = p.second; return *this; } - template <typename TT1, typename TT2> - Q_DECL_CONSTEXPR QPair(QPair<TT1, TT2> &&p) - noexcept((std::is_nothrow_constructible<T1, TT1>::value && - std::is_nothrow_constructible<T2, TT2>::value)) - // can't use std::move here as it's not constexpr in C++11: - : first(static_cast<TT1 &&>(p.first)), second(static_cast<TT2 &&>(p.second)) {} - template <typename TT1, typename TT2> - Q_DECL_RELAXED_CONSTEXPR QPair &operator=(QPair<TT1, TT2> &&p) - noexcept((std::is_nothrow_assignable<T1, TT1>::value && - std::is_nothrow_assignable<T2, TT2>::value)) - { first = std::move(p.first); second = std::move(p.second); return *this; } - - Q_DECL_RELAXED_CONSTEXPR void swap(QPair &other) - noexcept(noexcept(qSwap(other.first, other.first)) && noexcept(qSwap(other.second, other.second))) - { - // use qSwap() to pick up ADL swaps automatically: - qSwap(first, other.first); - qSwap(second, other.second); - } - - T1 first; - T2 second; -}; - -#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606 -template<class T1, class T2> -QPair(T1, T2) -> QPair<T1, T2>; +#if 0 +#pragma qt_class(QPair) #endif template <typename T1, typename T2> -void swap(QPair<T1, T2> &lhs, QPair<T1, T2> &rhs) noexcept(noexcept(lhs.swap(rhs))) -{ lhs.swap(rhs); } - -// mark QPair<T1,T2> as complex/movable/primitive depending on the -// typeinfos of the constituents: -template<class T1, class T2> -class QTypeInfo<QPair<T1, T2> > : public QTypeInfoMerger<QPair<T1, T2>, T1, T2> {}; // Q_DECLARE_TYPEINFO +using QPair = std::pair<T1, T2>; -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator==(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - noexcept(noexcept(p1.first == p2.first && p1.second == p2.second)) -{ return p1.first == p2.first && p1.second == p2.second; } - -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator!=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - noexcept(noexcept(!(p1 == p2))) -{ return !(p1 == p2); } - -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator<(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - noexcept(noexcept(p1.first < p2.first || (!(p2.first < p1.first) && p1.second < p2.second))) -{ - return p1.first < p2.first || (!(p2.first < p1.first) && p1.second < p2.second); -} - -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator>(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - noexcept(noexcept(p2 < p1)) -{ - return p2 < p1; -} - -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator<=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - noexcept(noexcept(!(p2 < p1))) -{ - return !(p2 < p1); -} - -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_INLINE_TEMPLATE bool operator>=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - noexcept(noexcept(!(p1 < p2))) +template <typename T1, typename T2> +constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) + noexcept(noexcept(std::make_pair(std::forward<T1>(value1), std::forward<T2>(value2)))) { - return !(p1 < p2); + return std::make_pair(std::forward<T1>(value1), std::forward<T2>(value2)); } -template <class T1, class T2> -Q_DECL_CONSTEXPR Q_OUTOFLINE_TEMPLATE QPair<T1, T2> qMakePair(const T1 &x, const T2 &y) - noexcept(noexcept(QPair<T1, T2>(x, y))) -{ - return QPair<T1, T2>(x, y); -} +template<class T1, class T2> +class QTypeInfo<std::pair<T1, T2>> : public QTypeInfoMerger<std::pair<T1, T2>, T1, T2> {}; QT_END_NAMESPACE diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc index 65576ef2e6..0e17b6c3b9 100644 --- a/src/corelib/tools/qpair.qdoc +++ b/src/corelib/tools/qpair.qdoc @@ -28,255 +28,24 @@ /*! \class QPair \inmodule QtCore - \reentrant - \brief The QPair class is a template class that stores a pair of items. + \obsolete + \brief QPair is an alias for std::pair. \ingroup tools - QPair\<T1, T2\> can be used in your application if the STL \c - pair type is not available. It stores one value of type T1 and - one value of type T2. It can be used as a return value for a - function that needs to return two values, or as the value type of - a \l{Container classes}{generic container}. - - Here's an example of a QPair that stores one QString and one \c - double value: - - \snippet code/doc_src_qpair.cpp 0 - - The components are accessible as public data members called \l - first and \l second. For example: - - \snippet code/doc_src_qpair.cpp 1 - - Note, however, that it is almost always preferable to define a small struct - to hold the result of a function with multiple return values. A struct - trivially generalizes to more than two values, and allows more descriptive - member names than \c{first} and \c{second}: - - \snippet code/doc_src_qpair.cpp struct - - The advent of C++11 automatic variable type deduction (\c{auto}) shifts the - emphasis from the type name to the name of functions and members. Thus, QPair, - like \c{std::pair} and \c{std::tuple}, is mostly useful in generic (template) - code, where defining a dedicated type is not possible. - - QPair's template data types (T1 and T2) must be \l{assignable - data types}. You cannot, for example, store a QWidget as a value; - instead, store a QWidget *. A few functions have additional - requirements; these requirements are documented on a per-function - basis. + QPair\<T1, T2\> is a typedef for std::pair\<T1, T2\>. + It is provided for backwards compatibility. Use std::pair directly + instead. \sa {Container Classes} */ -/*! \typedef QPair::first_type - - The type of the first element in the pair (T1). - - \sa first -*/ - -/*! \typedef QPair::second_type - - The type of the second element in the pair (T2). - - \sa second -*/ - -/*! \variable QPair::first - - The first element in the pair. -*/ - -/*! \variable QPair::second - - The second element in the pair. -*/ - -/*! \fn template <class T1, class T2> QPair<T1, T2>::QPair() - - Constructs an empty pair. The \c first and \c second elements are - initialized with \l{default-constructed value}s. -*/ - -/*! - \fn template <class T1, class T2> QPair<T1, T2>::QPair(const T1 &value1, const T2 &value2) - - Constructs a pair and initializes the \c first element with \a - value1 and the \c second element with \a value2. - - \sa qMakePair() -*/ - -/*! -\fn template <class T1, class T2> void QPair<T1, T2>::swap(QPair &other) - - \since 5.5 - Swaps this pair with \a other. - - Equivalent to - \code - qSwap(this->first, other.first); - qSwap(this->second, other.second); - \endcode - - Swap overloads are found in namespace \c std as well as via - argument-dependent lookup (ADL) in the namespace of \c{T} . -*/ - -/*! -\fn template <class T1, class T2> void swap(QPair<T1, T2> &lhs, QPair<T1, T2> &rhs) - \overload - \relates QPair - \since 5.5 - - Swaps \a lhs with \a rhs. -*/ - -/*! - \fn template <class T1, class T2> template <typename TT1, typename TT2> QPair<T1, T2>::QPair(const QPair<TT1, TT2> &p) - \since 5.2 - - Constructs a pair from the other pair \a p, of types TT1 and TT2. This - constructor will fail if \c first cannot be initialized from \c p.first or - if \c second cannot be initialized from \c p.second. - - \sa qMakePair() -*/ - -/*! - \fn template <class T1, class T2> template <typename TT1, typename TT2> QPair<T1, T2>::QPair(QPair<TT1, TT2> &&p) - \since 5.2 - - Move-constructs a QPair instance, making it point to the same object that \a p was pointing to. -*/ - -/*! - \fn template <class T1, class T2> template <typename TT1, typename TT2> QPair & QPair<T1, T2>::operator=(const QPair<TT1, TT2> &p) - \since 5.2 - - Copies pair \a p into this pair. - - \sa qMakePair() -*/ - -/*! - \fn template <class T1, class T2> template <typename TT1, typename TT2> QPair & QPair<T1, T2>::operator=(QPair<TT1, TT2> &&p) - \since 5.2 - - Move-assigns pair \a p into this pair instance. -*/ - -/*! \fn template <class T1, class T2> bool operator==(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - - \relates QPair - - Returns \c true if \a p1 is equal to \a p2; otherwise returns \c false. - Two pairs compare equal if their \c first data members compare - equal and if their \c second data members compare equal. - - This function requires the T1 and T2 types to have an - implementation of \c operator==(). -*/ - -/*! \fn template <class T1, class T2> bool operator!=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - - \relates QPair - - Returns \c true if \a p1 is not equal to \a p2; otherwise returns - false. Two pairs compare as not equal if their \c first data - members are not equal or if their \c second data members are not - equal. - - This function requires the T1 and T2 types to have an - implementation of \c operator==(). -*/ - -/*! \fn template <class T1, class T2> bool operator<(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - - \relates QPair - - Returns \c true if \a p1 is less than \a p2; otherwise returns - false. The comparison is done on the \c first members of \a p1 - and \a p2; if they compare equal, the \c second members are - compared to break the tie. - - This function requires the T1 and T2 types to have an - implementation of \c operator<(). -*/ - -/*! \fn template <class T1, class T2> bool operator>(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - - \relates QPair - - Returns \c true if \a p1 is greater than \a p2; otherwise returns - false. The comparison is done on the \c first members of \a p1 - and \a p2; if they compare equal, the \c second members are - compared to break the tie. - - This function requires the T1 and T2 types to have an - implementation of \c operator<(). -*/ - -/*! \fn template <class T1, class T2> bool operator<=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - - \relates QPair - - Returns \c true if \a p1 is less than or equal to \a p2; otherwise - returns \c false. The comparison is done on the \c first members of - \a p1 and \a p2; if they compare equal, the \c second members are - compared to break the tie. - - This function requires the T1 and T2 types to have an - implementation of \c operator<(). -*/ - -/*! \fn template <class T1, class T2> bool operator>=(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2) - - \relates QPair - - Returns \c true if \a p1 is greater than or equal to \a p2; - otherwise returns \c false. The comparison is done on the \c first - members of \a p1 and \a p2; if they compare equal, the \c second - members are compared to break the tie. - - This function requires the T1 and T2 types to have an - implementation of \c operator<(). -*/ - /*! - \fn template <class T1, class T2> QPair<T1, T2> qMakePair(const T1 &value1, const T2 &value2) - - \relates QPair - - Returns a QPair\<T1, T2\> that contains \a value1 and \a value2. - Example: - - \snippet code/doc_src_qpair.cpp 2 - - This is equivalent to QPair<T1, T2>(\a value1, \a value2), but - usually requires less typing. -*/ - -/*! \fn template <class T1, class T2> QDataStream &operator>>(QDataStream &in, QPair<T1, T2> &pair) - - \relates QPair - - Reads a pair from stream \a in into \a pair. - - This function requires the T1 and T2 types to implement \c operator>>(). - - \sa {Serializing Qt Data Types} -*/ - -/*! \fn template <class T1, class T2> QDataStream &operator<<(QDataStream &out, const QPair<T1, T2> &pair) - + \fn template <class T1, class T2> QPair<T1, T2> qMakePair(T1 &&value1, T2 &&value2) + \obsolete \relates QPair - Writes the pair \a pair to stream \a out. - - This function requires the T1 and T2 types to implement \c operator<<(). - - \sa {Serializing Qt Data Types} + qMakePair forwards its arguments to std::make_pair, and returns + the resulting std::pair. It is provided for backwards compatibility. + Use std::make_pair directly instead. */ diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h index 74be406539..9e70554716 100644 --- a/src/network/ssl/qsslkey.h +++ b/src/network/ssl/qsslkey.h @@ -52,8 +52,6 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_SSL -template <typename A, typename B> struct QPair; - class QIODevice; class QSslKeyPrivate; diff --git a/src/opengl/qopengltimerquery.cpp b/src/opengl/qopengltimerquery.cpp index 44955d48fc..d5ef875efa 100644 --- a/src/opengl/qopengltimerquery.cpp +++ b/src/opengl/qopengltimerquery.cpp @@ -143,11 +143,11 @@ bool QOpenGLTimerQueryPrivate::create() // Check to see if we also need to resolve the functions for EXT_timer_query QSurfaceFormat f = context->format(); - if (f.version() <= qMakePair<int, int>(3, 2) + if (f.version() <= qMakePair(3, 2) && !context->hasExtension(QByteArrayLiteral("GL_ARB_timer_query")) && context->hasExtension(QByteArrayLiteral("GL_EXT_timer_query"))) { ext = new QExtTimerQueryHelper(context); - } else if (f.version() <= qMakePair<int, int>(3, 2) + } else if (f.version() <= qMakePair(3, 2) && !context->hasExtension(QByteArrayLiteral("GL_ARB_timer_query")) && !context->hasExtension(QByteArrayLiteral("GL_EXT_timer_query"))) { qWarning("QOpenGLTimerQuery requires one of:\n" @@ -530,11 +530,11 @@ bool QOpenGLTimeMonitorPrivate::create() // Check to see if we also need to resolve the functions for EXT_timer_query QSurfaceFormat f = context->format(); - if (f.version() <= qMakePair<int, int>(3, 2) + if (f.version() <= qMakePair(3, 2) && !context->hasExtension(QByteArrayLiteral("GL_ARB_timer_query")) && context->hasExtension(QByteArrayLiteral("GL_EXT_timer_query"))) { ext = new QExtTimerQueryHelper(context); - } else if (f.version() <= qMakePair<int, int>(3, 2) + } else if (f.version() <= qMakePair(3, 2) && !context->hasExtension(QByteArrayLiteral("GL_ARB_timer_query")) && !context->hasExtension(QByteArrayLiteral("GL_EXT_timer_query"))) { qWarning("QOpenGLTimeMonitor requires one of:\n" diff --git a/src/opengl/qopenglvertexarrayobject.cpp b/src/opengl/qopenglvertexarrayobject.cpp index 7f28a0bc61..44a0640567 100644 --- a/src/opengl/qopenglvertexarrayobject.cpp +++ b/src/opengl/qopenglvertexarrayobject.cpp @@ -176,7 +176,7 @@ bool QOpenGLVertexArrayObjectPrivate::create() vaoFuncsType = NotSupported; QSurfaceFormat format = ctx->format(); #if !QT_CONFIG(opengles2) - if (format.version() >= qMakePair<int, int>(3,2)) { + if (format.version() >= qMakePair(3,2)) { vaoFuncs.core_3_2 = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_2_Core>(ctx); vaoFuncsType = Core_3_2; vaoFuncs.core_3_2->glGenVertexArrays(1, &vao); diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm index 3da4ba5480..92c11cd5e9 100644 --- a/src/plugins/platforms/ios/qiostextinputoverlay.mm +++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm @@ -67,7 +67,7 @@ static SelectionPair querySelection() QGuiApplication::sendEvent(QGuiApplication::focusObject(), &query); int anchorPos = query.value(Qt::ImAnchorPosition).toInt(); int cursorPos = query.value(Qt::ImCursorPosition).toInt(); - return qMakePair<int, int>(anchorPos, cursorPos); + return qMakePair(anchorPos, cursorPos); } static bool hasSelection() diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 18175196ff..9455a66fdd 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -232,14 +232,6 @@ template<> inline char *toString(const QVariant &v) } template <typename T1, typename T2> -inline char *toString(const QPair<T1, T2> &pair) -{ - const QScopedArrayPointer<char> first(toString(pair.first)); - const QScopedArrayPointer<char> second(toString(pair.second)); - return toString(QString::asprintf("QPair(%s,%s)", first.data(), second.data())); -} - -template <typename T1, typename T2> inline char *toString(const std::pair<T1, T2> &pair) { const QScopedArrayPointer<char> first(toString(pair.first)); diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h index 2bd9206574..8165532366 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.h +++ b/src/widgets/graphicsview/qgraphicsitemanimation.h @@ -51,7 +51,6 @@ class QGraphicsItem; class QPointF; class QTimeLine; class QTransform; -template <class T1, class T2> struct QPair; class QGraphicsItemAnimationPrivate; class Q_WIDGETS_EXPORT QGraphicsItemAnimation : public QObject diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 6606b3f2f9..41928ddf1e 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -3918,7 +3918,7 @@ QPair<int,int> QTreeViewPrivate::startAndEndColumns(const QRect &rect) const start = (start == -1 ? 0 : start); end = (end == -1 ? header->count() - 1 : end); } - return qMakePair<int,int>(qMin(start, end), qMax(start, end)); + return qMakePair(qMin(start, end), qMax(start, end)); } bool QTreeViewPrivate::hasVisibleChildren(const QModelIndex& parent) const diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 9db2bb241a..0091636172 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -1381,7 +1381,12 @@ void tst_QMetaObject::normalizedType_data() QTest::newRow("template6") << "QVector<::Foo::Bar>" << "QVector<::Foo::Bar>"; QTest::newRow("template7") << "QVector<QVector<int> >" << "QVector<QVector<int>>"; QTest::newRow("template8") << "QMap<const int, const short*>" << "QMap<const int,const short*>"; - QTest::newRow("template9") << "QPair<const QPair<int, int const *> , QPair<QHash<int, const char*> > >" << "QPair<const QPair<int,const int*>,QPair<QHash<int,const char*>>>"; + QTest::newRow("template9") << "QPair<const QPair<int, int const *> , QPair<QHash<int, const char*> > >" +#ifdef _LIBCPP_VERSION + << "std::__1::pair<const std::__1::pair<int,const int*>,std::__1::pair<QHash<int,const char*>>>"; +#else + << "std::pair<const std::pair<int,const int*>,std::pair<QHash<int,const char*>>>"; +#endif QTest::newRow("template10") << "QList<int const * const> const" << "QVector<const int*const>"; QTest::newRow("template11") << " QSharedPointer<QVarLengthArray< QString const, ( 16>> 2 )> > const & " << "QSharedPointer<QVarLengthArray<const QString,(16>>2)>>"; diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index d036be55c6..2688d90b43 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -1640,7 +1640,7 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2); } { - IntUIntPair intUIntPair = qMakePair<int, uint>(4, 2); + IntUIntPair intUIntPair = qMakePair(4, 2u); QCOMPARE(QVariant::fromValue(intUIntPair).value<IntUIntPair>().first, 4); QCOMPARE(QVariant::fromValue(intUIntPair).value<IntUIntPair>().second, (uint)2); } @@ -1727,7 +1727,7 @@ void tst_QMetaType::automaticTemplateRegistration() #define FOR_EACH_2ARG_TEMPLATE_TYPE(F, RealName1, RealName2) \ F(QHash, RealName1, RealName2) \ F(QMap, RealName1, RealName2) \ - F(QPair, RealName1, RealName2) + F(std::pair, RealName1, RealName2) #define PRINT_2ARG_TEMPLATE_INTERNAL(RealName1, RealName2) \ FOR_EACH_2ARG_TEMPLATE_TYPE(CREATE_AND_VERIFY_CONTAINER, RealName1, RealName2) @@ -1753,7 +1753,7 @@ void tst_QMetaType::automaticTemplateRegistration() CREATE_AND_VERIFY_CONTAINER(QVector, void*) CREATE_AND_VERIFY_CONTAINER(QVector, const void*) CREATE_AND_VERIFY_CONTAINER(QList, void*) - CREATE_AND_VERIFY_CONTAINER(QPair, void*, void*) + CREATE_AND_VERIFY_CONTAINER(std::pair, void*, void*) CREATE_AND_VERIFY_CONTAINER(QHash, void*, void*) CREATE_AND_VERIFY_CONTAINER(QHash, const void*, const void*) diff --git a/tests/auto/corelib/tools/qpair/qpair.pro b/tests/auto/corelib/tools/qpair/qpair.pro index d684a24a57..39757d3e0f 100644 --- a/tests/auto/corelib/tools/qpair/qpair.pro +++ b/tests/auto/corelib/tools/qpair/qpair.pro @@ -3,5 +3,4 @@ TARGET = tst_qpair QT = core testlib SOURCES = tst_qpair.cpp -# Force C++17 if available (needed due to Q_COMPILER_DEDUCTION_GUIDES) -contains(QT_CONFIG, c++1z): CONFIG += c++1z +contains(QT_CONFIG, c++2a): CONFIG += c++2a diff --git a/tests/auto/corelib/tools/qpair/tst_qpair.cpp b/tests/auto/corelib/tools/qpair/tst_qpair.cpp index 3c972329bc..0a158e5860 100644 --- a/tests/auto/corelib/tools/qpair/tst_qpair.cpp +++ b/tests/auto/corelib/tools/qpair/tst_qpair.cpp @@ -39,7 +39,7 @@ private Q_SLOTS: void testConstexpr(); void testConversions(); void taskQTBUG_48780_pairContainingCArray(); - void testDeducationRules(); + void testDeductionRules(); }; class C { C() {} char _[4]; }; @@ -203,9 +203,9 @@ void tst_QPair::taskQTBUG_48780_pairContainingCArray() Q_UNUSED(pair); } -void tst_QPair::testDeducationRules() +void tst_QPair::testDeductionRules() { -#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606 +#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201907L QPair p1{1, 2}; static_assert(std::is_same<decltype(p1)::first_type, decltype(1)>::value); static_assert(std::is_same<decltype(p1)::second_type, decltype(2)>::value); @@ -224,7 +224,7 @@ void tst_QPair::testDeducationRules() QCOMPARE(p3.first, "string"); QCOMPARE(p3.second, 2); #else - QSKIP("Unsupported"); + QSKIP("Unsupported (requires C++20's CTAD for aliases)"); #endif } diff --git a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp index 8cef351554..94a998a6a6 100644 --- a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp +++ b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp @@ -82,7 +82,7 @@ void tst_QAuthenticator::basicAuth() QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); QList<QPair<QByteArray, QByteArray> > headers; - headers << qMakePair<QByteArray, QByteArray>(QByteArray("WWW-Authenticate"), "Basic " + data.toUtf8()); + headers << qMakePair(QByteArray("WWW-Authenticate"), "Basic " + data.toUtf8()); priv->parseHttpResponse(headers, /*isProxy = */ false); QCOMPARE(auth.realm(), realm); @@ -130,7 +130,7 @@ void tst_QAuthenticator::ntlmAuth() // This phase of NTLM contains no information, other than what we're willing to negotiate // Current implementation uses flags: // NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET - headers << qMakePair<QByteArray, QByteArray>("WWW-Authenticate", "NTLM"); + headers << qMakePair(QByteArrayLiteral("WWW-Authenticate"), QByteArrayLiteral("NTLM")); priv->parseHttpResponse(headers, /*isProxy = */ false); if (sso) QVERIFY(priv->calculateResponse("GET", "/", "").startsWith("NTLM ")); @@ -139,7 +139,7 @@ void tst_QAuthenticator::ntlmAuth() // NTLM phase 2: challenge headers.clear(); - headers << qMakePair<QByteArray, QByteArray>(QByteArray("WWW-Authenticate"), "NTLM " + data.toUtf8()); + headers << qMakePair(QByteArray("WWW-Authenticate"), "NTLM " + data.toUtf8()); priv->parseHttpResponse(headers, /*isProxy = */ false); QEXPECT_FAIL("with-realm", "NTLM authentication code doesn't extract the realm", Continue); diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.junitxml b/tests/auto/testlib/selftests/expected_pairdiagnostics.junitxml index cf2a30b84a..653dde11c0 100644 --- a/tests/auto/testlib/selftests/expected_pairdiagnostics.junitxml +++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.junitxml @@ -8,8 +8,8 @@ <testcase result="pass" name="initTestCase"/> <testcase result="fail" name="testQPair"> <failure message="Compared values are not the same - Actual (pair1): "QPair(1,1)" - Expected (pair2): "QPair(1,2)"" result="fail"/> + Actual (pair1): "std::pair(1,1)" + Expected (pair2): "std::pair(1,2)"" result="fail"/> </testcase> <testcase result="fail" name="testStdPair"> <failure message="Compared values are not the same diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.lightxml b/tests/auto/testlib/selftests/expected_pairdiagnostics.lightxml index 7a842e9d36..e4ceacc9e3 100644 --- a/tests/auto/testlib/selftests/expected_pairdiagnostics.lightxml +++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.lightxml @@ -10,8 +10,8 @@ <TestFunction name="testQPair"> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp" line="0"> <Description><![CDATA[Compared values are not the same - Actual (pair1): "QPair(1,1)" - Expected (pair2): "QPair(1,2)"]]></Description> + Actual (pair1): "std::pair(1,1)" + Expected (pair2): "std::pair(1,2)"]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.tap b/tests/auto/testlib/selftests/expected_pairdiagnostics.tap index 9c45880c2d..d6e1a0b22f 100644 --- a/tests/auto/testlib/selftests/expected_pairdiagnostics.tap +++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.tap @@ -5,10 +5,10 @@ not ok 2 - testQPair() --- type: QCOMPARE message: Compared values are not the same - wanted: "QPair(1,2)" (pair2) - found: "QPair(1,1)" (pair1) - expected: "QPair(1,2)" (pair2) - actual: "QPair(1,1)" (pair1) + wanted: "std::pair(1,2)" (pair2) + found: "std::pair(1,1)" (pair1) + expected: "std::pair(1,2)" (pair2) + actual: "std::pair(1,1)" (pair1) at: tst_PairDiagnostics::testQPair() (qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp:51) file: qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp line: 51 diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.teamcity b/tests/auto/testlib/selftests/expected_pairdiagnostics.teamcity index 9068e2c45b..a86f4fa254 100644 --- a/tests/auto/testlib/selftests/expected_pairdiagnostics.teamcity +++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.teamcity @@ -2,7 +2,7 @@ ##teamcity[testStarted name='initTestCase()' flowId='tst_PairDiagnostics'] ##teamcity[testFinished name='initTestCase()' flowId='tst_PairDiagnostics'] ##teamcity[testStarted name='testQPair()' flowId='tst_PairDiagnostics'] -##teamcity[testFailed name='testQPair()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (pair1): "QPair(1,1)"|n Expected (pair2): "QPair(1,2)"' flowId='tst_PairDiagnostics'] +##teamcity[testFailed name='testQPair()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (pair1): "std::pair(1,1)"|n Expected (pair2): "std::pair(1,2)"' flowId='tst_PairDiagnostics'] ##teamcity[testFinished name='testQPair()' flowId='tst_PairDiagnostics'] ##teamcity[testStarted name='testStdPair()' flowId='tst_PairDiagnostics'] ##teamcity[testFailed name='testStdPair()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (pair1): "std::pair(1,1)"|n Expected (pair2): "std::pair(1,2)"' flowId='tst_PairDiagnostics'] diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.txt b/tests/auto/testlib/selftests/expected_pairdiagnostics.txt index 5e29888ba6..cbb8b764ff 100644 --- a/tests/auto/testlib/selftests/expected_pairdiagnostics.txt +++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.txt @@ -2,8 +2,8 @@ Config: Using QtTest library PASS : tst_PairDiagnostics::initTestCase() FAIL! : tst_PairDiagnostics::testQPair() Compared values are not the same - Actual (pair1): "QPair(1,1)" - Expected (pair2): "QPair(1,2)" + Actual (pair1): "std::pair(1,1)" + Expected (pair2): "std::pair(1,2)" Loc: [qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp(0)] FAIL! : tst_PairDiagnostics::testStdPair() Compared values are not the same Actual (pair1): "std::pair(1,1)" diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.xml b/tests/auto/testlib/selftests/expected_pairdiagnostics.xml index cd98e4d36e..89e8ca49a6 100644 --- a/tests/auto/testlib/selftests/expected_pairdiagnostics.xml +++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.xml @@ -12,8 +12,8 @@ <TestFunction name="testQPair"> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp" line="0"> <Description><![CDATA[Compared values are not the same - Actual (pair1): "QPair(1,1)" - Expected (pair2): "QPair(1,2)"]]></Description> + Actual (pair1): "std::pair(1,1)" + Expected (pair2): "std::pair(1,2)"]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> |