diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-07-06 14:06:08 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-08-15 14:43:30 +0200 |
commit | 3ef8ec2ee187b949b3f6840ca03bcc0e814c00a9 (patch) | |
tree | 2d9794d1b2ec0ec1caa8f8da3bf6ddc32fb9d894 /src/corelib/serialization/qdatastream.h | |
parent | 8ad9e81694fda39fbecebb9f97491004e9ac8c41 (diff) |
Constrain the data stream operators for containers
Check that we can successfully instantiate the data
stream operator for a container before we actually try.
This is required so we can automate registration of debug
stream operators with QMetaType.
Change-Id: Ib100a5242470d7fc8067058cc4d81af2fa9354b0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/serialization/qdatastream.h')
-rw-r--r-- | src/corelib/serialization/qdatastream.h | 35 |
1 files changed, 21 insertions, 14 deletions
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; |