summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qtypeinfo.h11
-rw-r--r--src/corelib/serialization/qdatastream.h35
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp10
-rw-r--r--tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp8
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