diff options
-rw-r--r-- | src/corelib/global/qtypeinfo.h | 17 | ||||
-rw-r--r-- | src/corelib/io/qdebug.h | 16 | ||||
-rw-r--r-- | src/corelib/serialization/qdatastream.h | 31 | ||||
-rw-r--r-- | src/corelib/tools/qhash.h | 4 | ||||
-rw-r--r-- | src/corelib/tools/qlist.h | 12 | ||||
-rw-r--r-- | src/corelib/tools/qmap.h | 8 | ||||
-rw-r--r-- | src/corelib/tools/qset.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/tools/collections/tst_collections.cpp | 144 |
8 files changed, 204 insertions, 32 deletions
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 58f20b7be4..2729217aab 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -335,17 +335,29 @@ struct has_operator_equal : detail::expand_operator_equal<T> {}; template<typename T> inline constexpr bool has_operator_equal_v = has_operator_equal<T>::value; +template <typename Container, typename T> +using has_operator_equal_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T>>; + template<typename T> struct has_operator_less_than : detail::expand_operator_less_than<T> {}; template<typename T> inline constexpr bool has_operator_less_than_v = has_operator_less_than<T>::value; +template <typename Container, typename T> +using has_operator_less_than_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_less_than<T>>; + template <typename ...T> using compare_eq_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal<T>...>, bool>; +template <typename Container, typename ...T> +using compare_eq_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal_container<Container, T>...>, bool>; + template <typename ...T> using compare_lt_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than<T>...>, bool>; +template <typename Container, typename ...T> +using compare_lt_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>...>, bool>; + namespace detail { template<typename T> @@ -363,6 +375,9 @@ struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<St template <typename Stream, typename T> inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value; +template <typename Stream, typename Container, typename T> +using has_ostream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_ostream_operator<Stream, T>>; + template <typename Stream, typename, typename = void> struct has_istream_operator : std::false_type {}; template <typename Stream, typename T> @@ -370,6 +385,8 @@ struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<St : std::true_type {}; template <typename Stream, typename T> inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value; +template <typename Stream, typename Container, typename T> +using has_istream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_istream_operator<Stream, T>>; template <typename Stream, typename T> inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>; diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 29da386c1b..d1c2fea494 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -243,8 +243,12 @@ template<typename ...T> using QDebugIfHasDebugStream = std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDebug, T>...>, QDebug>; +template<typename Container, typename ...T> +using QDebugIfHasDebugStreamContainer = + std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator_container<QDebug, Container, T>...>, QDebug>; + template<typename T> -inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QList<T> &vec) +inline QDebugIfHasDebugStreamContainer<QList<T>, T> operator<<(QDebug debug, const QList<T> &vec) { return QtPrivate::printSequentialContainer(debug, "QList", vec); } @@ -274,25 +278,25 @@ inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const std::multim } template <class Key, class T> -inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QMap<Key, T> &map) +inline QDebugIfHasDebugStreamContainer<QMap<Key, T>, Key, T> operator<<(QDebug debug, const QMap<Key, T> &map) { return QtPrivate::printAssociativeContainer(debug, "QMap", map); } template <class Key, class T> -inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QMultiMap<Key, T> &map) +inline QDebugIfHasDebugStreamContainer<QMultiMap<Key, T>, Key, T> operator<<(QDebug debug, const QMultiMap<Key, T> &map) { return QtPrivate::printAssociativeContainer(debug, "QMultiMap", map); } template <class Key, class T> -inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QHash<Key, T> &hash) +inline QDebugIfHasDebugStreamContainer<QHash<Key, T>, Key, T> operator<<(QDebug debug, const QHash<Key, T> &hash) { return QtPrivate::printAssociativeContainer(debug, "QHash", hash); } template <class Key, class T> -inline QDebugIfHasDebugStream<Key, T> operator<<(QDebug debug, const QMultiHash<Key, T> &hash) +inline QDebugIfHasDebugStreamContainer<QMultiHash<Key, T>, Key, T> operator<<(QDebug debug, const QMultiHash<Key, T> &hash) { return QtPrivate::printAssociativeContainer(debug, "QMultiHash", hash); } @@ -306,7 +310,7 @@ inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T } template <typename T> -inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const QSet<T> &set) +inline QDebugIfHasDebugStreamContainer<QSet<T>, T> operator<<(QDebug debug, const QSet<T> &set) { return QtPrivate::printSequentialContainer(debug, "QSet", set); } diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index 523dabfdc6..1ec9704a6a 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -351,9 +351,16 @@ QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c) template<typename ...T> using QDataStreamIfHasOStreamOperators = std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDataStream, T>...>, QDataStream &>; +template<typename Container, typename ...T> +using QDataStreamIfHasOStreamOperatorsContainer = + std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator_container<QDataStream, Container, T>...>, QDataStream &>; + template<typename ...T> using QDataStreamIfHasIStreamOperators = std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator<QDataStream, T>...>, QDataStream &>; +template<typename Container, typename ...T> +using QDataStreamIfHasIStreamOperatorsContainer = + std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator_container<QDataStream, Container, T>...>, QDataStream &>; /***************************************************************************** QDataStream inline functions @@ -425,74 +432,74 @@ operator>>(QDataStream &s, T &t) { return s >> reinterpret_cast<typename std::underlying_type<T>::type &>(t); } template<typename T> -inline QDataStreamIfHasIStreamOperators<T> operator>>(QDataStream &s, QList<T> &v) +inline QDataStreamIfHasIStreamOperatorsContainer<QList<T>, T> operator>>(QDataStream &s, QList<T> &v) { return QtPrivate::readArrayBasedContainer(s, v); } template<typename T> -inline QDataStreamIfHasOStreamOperators<T> operator<<(QDataStream &s, const QList<T> &v) +inline QDataStreamIfHasOStreamOperatorsContainer<QList<T>, T> operator<<(QDataStream &s, const QList<T> &v) { return QtPrivate::writeSequentialContainer(s, v); } template <typename T> -inline QDataStreamIfHasIStreamOperators<T> operator>>(QDataStream &s, QSet<T> &set) +inline QDataStreamIfHasIStreamOperatorsContainer<QSet<T>, T> operator>>(QDataStream &s, QSet<T> &set) { return QtPrivate::readListBasedContainer(s, set); } template <typename T> -inline QDataStreamIfHasOStreamOperators<T> operator<<(QDataStream &s, const QSet<T> &set) +inline QDataStreamIfHasOStreamOperatorsContainer<QSet<T>, T> operator<<(QDataStream &s, const QSet<T> &set) { return QtPrivate::writeSequentialContainer(s, set); } template <class Key, class T> -inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QHash<Key, T> &hash) +inline QDataStreamIfHasIStreamOperatorsContainer<QHash<Key, T>, Key, T> operator>>(QDataStream &s, QHash<Key, T> &hash) { return QtPrivate::readAssociativeContainer(s, hash); } template <class Key, class T> -inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QHash<Key, T> &hash) +inline QDataStreamIfHasOStreamOperatorsContainer<QHash<Key, T>, Key, T> operator<<(QDataStream &s, const QHash<Key, T> &hash) { return QtPrivate::writeAssociativeContainer(s, hash); } template <class Key, class T> -inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QMultiHash<Key, T> &hash) +inline QDataStreamIfHasIStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator>>(QDataStream &s, QMultiHash<Key, T> &hash) { return QtPrivate::readAssociativeContainer(s, hash); } template <class Key, class T> -inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QMultiHash<Key, T> &hash) +inline QDataStreamIfHasOStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiHash<Key, T> &hash) { return QtPrivate::writeAssociativeMultiContainer(s, hash); } template <class Key, class T> -inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QMap<Key, T> &map) +inline QDataStreamIfHasIStreamOperatorsContainer<QMap<Key, T>, Key, T> operator>>(QDataStream &s, QMap<Key, T> &map) { return QtPrivate::readAssociativeContainer(s, map); } template <class Key, class T> -inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QMap<Key, T> &map) +inline QDataStreamIfHasOStreamOperatorsContainer<QMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMap<Key, T> &map) { return QtPrivate::writeAssociativeContainer(s, map); } template <class Key, class T> -inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QMultiMap<Key, T> &map) +inline QDataStreamIfHasIStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator>>(QDataStream &s, QMultiMap<Key, T> &map) { return QtPrivate::readAssociativeContainer(s, map); } template <class Key, class T> -inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QMultiMap<Key, T> &map) +inline QDataStreamIfHasOStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiMap<Key, T> &map) { return QtPrivate::writeAssociativeMultiContainer(s, map); } diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 38f23d822f..9145891faf 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -820,7 +820,7 @@ public: void swap(QHash &other) noexcept { qSwap(d, other.d); } template <typename U = T> - QTypeTraits::compare_eq_result<U> operator==(const QHash &other) const noexcept + QTypeTraits::compare_eq_result_container<QHash, U> operator==(const QHash &other) const noexcept { if (d == other.d) return true; @@ -836,7 +836,7 @@ public: return true; } template <typename U = T> - QTypeTraits::compare_eq_result<U> operator!=(const QHash &other) const noexcept + QTypeTraits::compare_eq_result_container<QHash, U> operator!=(const QHash &other) const noexcept { return !(*this == other); } inline qsizetype size() const noexcept { return d ? qsizetype(d->size) : 0; } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index ddce07bbb7..0329dd37da 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -290,7 +290,7 @@ public: void swap(QList<T> &other) noexcept { qSwap(d, other.d); } template <typename U = T> - QTypeTraits::compare_eq_result<U> operator==(const QList &other) const + QTypeTraits::compare_eq_result_container<QList, U> operator==(const QList &other) const { if (size() != other.size()) return false; @@ -301,13 +301,13 @@ public: return d->compare(begin(), other.begin(), size()); } template <typename U = T> - QTypeTraits::compare_eq_result<U> operator!=(const QList &other) const + QTypeTraits::compare_eq_result_container<QList, U> operator!=(const QList &other) const { return !(*this == other); } template <typename U = T> - QTypeTraits::compare_lt_result<U> operator<(const QList &other) const + QTypeTraits::compare_lt_result_container<QList, U> operator<(const QList &other) const noexcept(noexcept(std::lexicographical_compare<typename QList<U>::const_iterator, typename QList::const_iterator>( std::declval<QList<U>>().begin(), std::declval<QList<U>>().end(), @@ -318,21 +318,21 @@ public: } template <typename U = T> - QTypeTraits::compare_lt_result<U> operator>(const QList &other) const + QTypeTraits::compare_lt_result_container<QList, U> operator>(const QList &other) const noexcept(noexcept(other < std::declval<QList<U>>())) { return other < *this; } template <typename U = T> - QTypeTraits::compare_lt_result<U> operator<=(const QList &other) const + QTypeTraits::compare_lt_result_container<QList, U> operator<=(const QList &other) const noexcept(noexcept(other < std::declval<QList<U>>())) { return !(other < *this); } template <typename U = T> - QTypeTraits::compare_lt_result<U> operator>=(const QList &other) const + QTypeTraits::compare_lt_result_container<QList, U> operator>=(const QList &other) const noexcept(noexcept(std::declval<QList<U>>() < other)) { return !(*this < other); diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index d5f6b91ba8..57a964f29f 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -277,7 +277,7 @@ public: } template <typename AKey = Key, typename AT = T> friend - QTypeTraits::compare_eq_result<AKey, AT> operator==(const QMap &lhs, const QMap &rhs) + QTypeTraits::compare_eq_result_container<QMap, AKey, AT> operator==(const QMap &lhs, const QMap &rhs) { if (lhs.d == rhs.d) return true; @@ -288,7 +288,7 @@ public: } template <typename AKey = Key, typename AT = T> friend - QTypeTraits::compare_eq_result<AKey, AT> operator!=(const QMap &lhs, const QMap &rhs) + QTypeTraits::compare_eq_result_container<QMap, AKey, AT> operator!=(const QMap &lhs, const QMap &rhs) { return !(lhs == rhs); } @@ -905,7 +905,7 @@ public: } template <typename AKey = Key, typename AT = T> friend - QTypeTraits::compare_eq_result<AKey, AT> operator==(const QMultiMap &lhs, const QMultiMap &rhs) + QTypeTraits::compare_eq_result_container<QMultiMap, AKey, AT> operator==(const QMultiMap &lhs, const QMultiMap &rhs) { if (lhs.d == rhs.d) return true; @@ -916,7 +916,7 @@ public: } template <typename AKey = Key, typename AT = T> friend - QTypeTraits::compare_eq_result<AKey, AT> operator!=(const QMultiMap &lhs, const QMultiMap &rhs) + QTypeTraits::compare_eq_result_container<QMultiMap, AKey, AT> operator!=(const QMultiMap &lhs, const QMultiMap &rhs) { return !(lhs == rhs); } diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 681ce9cbe2..565b8b5691 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -72,10 +72,10 @@ public: inline void swap(QSet<T> &other) noexcept { q_hash.swap(other.q_hash); } template <typename U = T> - QTypeTraits::compare_eq_result<U> operator==(const QSet<T> &other) const + QTypeTraits::compare_eq_result_container<QSet, U> operator==(const QSet<T> &other) const { return q_hash == other.q_hash; } template <typename U = T> - QTypeTraits::compare_eq_result<U> operator!=(const QSet<T> &other) const + QTypeTraits::compare_eq_result_container<QSet, U> operator!=(const QSet<T> &other) const { return q_hash != other.q_hash; } inline qsizetype size() const { return q_hash.size(); } diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index 9dbaa9c386..0fa252427a 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -160,6 +160,150 @@ struct Pod { int i1, i2; }; +// Compile-time checks for recursive containers +struct Dummy +{ + bool operator==(const Dummy &) const { return false; } + bool operator<(const Dummy &) const { return false; } +}; + +struct RecursiveList : public QList<RecursiveList> {}; +struct RecursiveSet : public QSet<RecursiveSet> {}; +struct RecursiveMapV : public QMap<Dummy, RecursiveMapV> {}; +struct RecursiveMapK : public QMap<RecursiveMapK, Dummy> {}; +struct RecursiveMultiMapV : public QMultiMap<Dummy, RecursiveMultiMapV> {}; +struct RecursiveMultiMapK : public QMultiMap<RecursiveMultiMapK, Dummy> {}; +struct RecursiveHashV : public QHash<Dummy, RecursiveHashV> {}; +struct RecursiveHashK : public QHash<RecursiveHashK, Dummy> {}; +struct RecursiveMultiHashV : public QMultiHash<Dummy, RecursiveMultiHashV> {}; +struct RecursiveMultiHashK : public QMultiHash<RecursiveMultiHashK, Dummy> {}; + +struct Empty {}; +struct NoCmpParamRecursiveMapV : public QMap<Empty, NoCmpParamRecursiveMapV> {}; +struct NoCmpParamRecursiveMapK : public QMap<NoCmpParamRecursiveMapK, Empty> {}; +struct NoCmpParamRecursiveMultiMapV : public QMultiMap<Empty, NoCmpParamRecursiveMultiMapV> {}; +struct NoCmpParamRecursiveMultiMapK : public QMultiMap<NoCmpParamRecursiveMultiMapK, Empty> {}; +struct NoCmpParamRecursiveHashV : public QHash<Empty, NoCmpParamRecursiveHashV> {}; +struct NoCmpParamRecursiveHashK : public QHash<NoCmpParamRecursiveHashK, Empty> {}; +struct NoCmpParamRecursiveMultiHashV : public QMultiHash<Empty, NoCmpParamRecursiveMultiHashV> {}; +struct NoCmpParamRecursiveMultiHashK : public QMultiHash<NoCmpParamRecursiveMultiHashK, Empty> {}; + +struct NoCmpRecursiveList : public QList<NoCmpRecursiveList> +{ + bool operator==(const RecursiveList &) const = delete; + bool operator<(const RecursiveList &) const = delete; +}; +struct NoCmpRecursiveSet : public QSet<NoCmpRecursiveSet> +{ + bool operator==(const NoCmpRecursiveSet &) const = delete; +}; +struct NoCmpRecursiveMapV : public QMap<Dummy, NoCmpRecursiveMapV> +{ + bool operator==(const NoCmpRecursiveMapV &) const = delete; +}; +struct NoCmpRecursiveMapK : public QMap<NoCmpRecursiveMapK, Dummy> +{ + bool operator==(const NoCmpRecursiveMapK &) const = delete; +}; +struct NoCmpRecursiveMultiMapV : public QMultiMap<Dummy, NoCmpRecursiveMultiMapV> +{ + bool operator==(const NoCmpRecursiveMultiMapV &) const = delete; +}; +struct NoCmpRecursiveMultiMapK : public QMultiMap<NoCmpRecursiveMultiMapK, Dummy> +{ + bool operator==(const NoCmpRecursiveMultiMapK &) const = delete; +}; +struct NoCmpRecursiveHashV : public QHash<Dummy, NoCmpRecursiveHashV> +{ + bool operator==(const NoCmpRecursiveHashV &) const = delete; +}; +struct NoCmpRecursiveHashK : public QHash<NoCmpRecursiveHashK, Dummy> +{ + bool operator==(const NoCmpRecursiveHashK &) const = delete; +}; +struct NoCmpRecursiveMultiHashV : public QMultiHash<Dummy, NoCmpRecursiveMultiHashV> +{ + bool operator==(const NoCmpRecursiveMultiHashV &) const = delete; +}; +struct NoCmpRecursiveMultiHashK : public QMultiHash<NoCmpRecursiveMultiHashK, Dummy> +{ + bool operator==(const NoCmpRecursiveMultiHashK &) const = delete; +}; + +uint qHash(const Dummy &) { return 0; } +uint qHash(const RecursiveSet &) { return 0; } +uint qHash(const RecursiveHashK &) { return 0; } +uint qHash(const RecursiveHashV &) { return 0; } +uint qHash(const RecursiveMultiHashK &) { return 0; } +uint qHash(const RecursiveMultiHashV &) { return 0; } + +Q_DECLARE_METATYPE(RecursiveList); +Q_DECLARE_METATYPE(RecursiveSet); +Q_DECLARE_METATYPE(RecursiveMapV); +Q_DECLARE_METATYPE(RecursiveMapK); +Q_DECLARE_METATYPE(RecursiveMultiMapV); +Q_DECLARE_METATYPE(RecursiveMultiMapK); +Q_DECLARE_METATYPE(RecursiveHashV); +Q_DECLARE_METATYPE(RecursiveHashK); +Q_DECLARE_METATYPE(RecursiveMultiHashV); +Q_DECLARE_METATYPE(RecursiveMultiHashK); + +Q_DECLARE_METATYPE(NoCmpParamRecursiveMapV); +Q_DECLARE_METATYPE(NoCmpParamRecursiveMapK); +Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiMapV); +Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiMapK); +Q_DECLARE_METATYPE(NoCmpParamRecursiveHashK); +// TODO: fix, this requires operator== from key type (QTBUG-96256) +// Q_DECLARE_METATYPE(NoCmpParamRecursiveHashV); +Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashK); +// TODO: fix, this requires operator== from key type (QTBUG-96256) +// Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashK); + +Q_DECLARE_METATYPE(NoCmpRecursiveList); +// TODO: fix, this requires operator== (QTBUG-96257) +// Q_DECLARE_METATYPE(NoCmpRecursiveSet); +Q_DECLARE_METATYPE(NoCmpRecursiveMapV); +Q_DECLARE_METATYPE(NoCmpRecursiveMapK); +Q_DECLARE_METATYPE(NoCmpRecursiveMultiMapV); +Q_DECLARE_METATYPE(NoCmpRecursiveMultiMapK); +Q_DECLARE_METATYPE(NoCmpRecursiveHashV); +Q_DECLARE_METATYPE(NoCmpRecursiveHashK); +Q_DECLARE_METATYPE(NoCmpRecursiveMultiHashV); +Q_DECLARE_METATYPE(NoCmpRecursiveMultiHashK); + +static_assert(QTypeTraits::has_operator_equal_v<RecursiveList>); +static_assert(QTypeTraits::has_operator_less_than_v<RecursiveList>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveSet>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveMapV>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveMapK>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiMapV>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiMapK>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveHashV>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveHashK>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiHashV>); +static_assert(QTypeTraits::has_operator_equal_v<RecursiveMultiHashK>); + +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMapV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMapK>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiMapV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiMapK>); +static_assert(QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashK>); +static_assert(QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashK>); + +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveList>); +static_assert(!QTypeTraits::has_operator_less_than_v<NoCmpRecursiveList>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveSet>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMapV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMapK>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiMapV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiMapK>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveHashV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveHashK>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiHashV>); +static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveMultiHashK>); + void tst_Collections::typeinfo() { QVERIFY(QTypeInfo<int*>::isPointer); |