diff options
-rw-r--r-- | src/corelib/global/qtypeinfo.h | 11 | ||||
-rw-r--r-- | src/corelib/serialization/qdatastream.h | 35 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 10 | ||||
-rw-r--r-- | tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp | 8 |
4 files changed, 46 insertions, 18 deletions
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 2f7bb414b5..e45347ee10 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -464,6 +464,17 @@ struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<St template <typename Stream, typename T> constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value; +template <typename Stream, typename, typename = void> +struct has_istream_operator : std::false_type {}; +template <typename Stream, typename T> +struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>> + : std::true_type {}; +template <typename Stream, typename T> +constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value; + +template <typename Stream, typename T> +constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>; + } diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index d00fb5e7d8..48e96cb4c5 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -347,6 +347,13 @@ QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c) } // QtPrivate namespace +template<typename ...T> +using QDataStreamIfHasOStreamOperators = + std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDataStream, T>...>, QDataStream &>; +template<typename ...T> +using QDataStreamIfHasIStreamOperators = + std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator<QDataStream, T>...>, QDataStream &>; + /***************************************************************************** QDataStream inline functions *****************************************************************************/ @@ -406,88 +413,88 @@ operator>>(QDataStream &s, T &t) { return s >> reinterpret_cast<typename std::underlying_type<T>::type &>(t); } template<typename T> -inline QDataStream &operator>>(QDataStream &s, QList<T> &v) +inline QDataStreamIfHasIStreamOperators<T> operator>>(QDataStream &s, QList<T> &v) { return QtPrivate::readArrayBasedContainer(s, v); } template<typename T> -inline QDataStream &operator<<(QDataStream &s, const QList<T> &v) +inline QDataStreamIfHasOStreamOperators<T> operator<<(QDataStream &s, const QList<T> &v) { return QtPrivate::writeSequentialContainer(s, v); } template <typename T> -inline QDataStream &operator>>(QDataStream &s, QSet<T> &set) +inline QDataStreamIfHasIStreamOperators<T> operator>>(QDataStream &s, QSet<T> &set) { return QtPrivate::readListBasedContainer(s, set); } template <typename T> -inline QDataStream &operator<<(QDataStream &s, const QSet<T> &set) +inline QDataStreamIfHasOStreamOperators<T> operator<<(QDataStream &s, const QSet<T> &set) { return QtPrivate::writeSequentialContainer(s, set); } template <class Key, class T> -inline QDataStream &operator>>(QDataStream &s, QHash<Key, T> &hash) +inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QHash<Key, T> &hash) { return QtPrivate::readAssociativeContainer(s, hash); } template <class Key, class T> -inline QDataStream &operator<<(QDataStream &s, const QHash<Key, T> &hash) +inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QHash<Key, T> &hash) { return QtPrivate::writeAssociativeContainer(s, hash); } template <class Key, class T> -inline QDataStream &operator>>(QDataStream &s, QMultiHash<Key, T> &hash) +inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QMultiHash<Key, T> &hash) { return QtPrivate::readAssociativeContainer(s, hash); } template <class Key, class T> -inline QDataStream &operator<<(QDataStream &s, const QMultiHash<Key, T> &hash) +inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QMultiHash<Key, T> &hash) { return QtPrivate::writeAssociativeMultiContainer(s, hash); } template <class Key, class T> -inline QDataStream &operator>>(QDataStream &s, QMap<Key, T> &map) +inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QMap<Key, T> &map) { return QtPrivate::readAssociativeContainer(s, map); } template <class Key, class T> -inline QDataStream &operator<<(QDataStream &s, const QMap<Key, T> &map) +inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QMap<Key, T> &map) { return QtPrivate::writeAssociativeContainer(s, map); } template <class Key, class T> -inline QDataStream &operator>>(QDataStream &s, QMultiMap<Key, T> &map) +inline QDataStreamIfHasIStreamOperators<Key, T> operator>>(QDataStream &s, QMultiMap<Key, T> &map) { return QtPrivate::readAssociativeContainer(s, map); } template <class Key, class T> -inline QDataStream &operator<<(QDataStream &s, const QMultiMap<Key, T> &map) +inline QDataStreamIfHasOStreamOperators<Key, T> operator<<(QDataStream &s, const QMultiMap<Key, T> &map) { return QtPrivate::writeAssociativeMultiContainer(s, map); } #ifndef QT_NO_DATASTREAM template <class T1, class T2> -inline QDataStream& operator>>(QDataStream& s, std::pair<T1, T2> &p) +inline QDataStreamIfHasIStreamOperators<T1, T2> 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 std::pair<T1, T2> &p) +inline QDataStreamIfHasOStreamOperators<T1, T2> operator<<(QDataStream& s, const std::pair<T1, T2> &p) { s << p.first << p.second; return s; diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 72412aa44d..0b54f53517 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -35,11 +35,13 @@ #include <QtConcurrentRun> #include <QFutureSynchronizer> -static_assert(QTypeTraits::has_ostream_v<QDebug, int>); -static_assert(QTypeTraits::has_ostream_v<QDebug, QList<int>>); +static_assert(QTypeTraits::has_ostream_operator_v<QDebug, int>); +static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QList<int>>); +static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, QString>>); struct NonStreamable {}; -static_assert(!QTypeTraits::has_ostream_v<QDebug, NonStreamable>); -static_assert(!QTypeTraits::has_ostream_v<QDebug, QList<NonStreamable>>); +static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, NonStreamable>); +static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QList<NonStreamable>>); +static_assert(!QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, NonStreamable>>); class tst_QDebug: public QObject { diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index 932c4d25d2..bd7100adec 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -36,6 +36,14 @@ #include <QtGui/QPixmap> #include <QtGui/QTextLength> +static_assert(QTypeTraits::has_ostream_operator_v<QDataStream, int>); +static_assert(QTypeTraits::has_ostream_operator_v<QDataStream, QList<int>>); +static_assert(QTypeTraits::has_ostream_operator_v<QDataStream, QMap<int, QString>>); +struct NonStreamable {}; +static_assert(!QTypeTraits::has_ostream_operator_v<QDataStream, NonStreamable>); +static_assert(!QTypeTraits::has_ostream_operator_v<QDataStream, QList<NonStreamable>>); +static_assert(!QTypeTraits::has_ostream_operator_v<QDataStream, QMap<int, NonStreamable>>); + class tst_QDataStream : public QObject { Q_OBJECT |