diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-01-24 09:08:35 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-02-03 17:43:30 +0100 |
commit | eea82ab75d3a10fd3389b39ef226ffae52ae45ae (patch) | |
tree | b3bfeb670679c0e22157a1847c38216643e99db5 | |
parent | 4681f1fc2cfabb64b6b4f1095e2d4f44d0cee903 (diff) |
Cleanup QDBusArgument marshalling for containers
There's no need to specialize the marshalling for QList, QHash and QMap
when we can simply have generic code here that works for all containers
Change-Id: I442ac6009953d2bd8e5a7012262cffeb8e912034
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/dbus/qdbusargument.cpp | 7 | ||||
-rw-r--r-- | src/dbus/qdbusargument.h | 106 |
2 files changed, 36 insertions, 77 deletions
diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp index 5a0f0f013b..7e1d847982 100644 --- a/src/dbus/qdbusargument.cpp +++ b/src/dbus/qdbusargument.cpp @@ -908,9 +908,10 @@ void QDBusArgument::endArray() \snippet code/src_qdbus_qdbusargument.cpp 7 - If the type you want to marshall is a QMap or QHash, you need not - declare an \c{operator<<} function for it, since Qt D-Bus provides - generic templates to do the job of marshalling the data. + You usually don't need to provide an \c{operator<<} or \c{operator>>} + function for associative containers such as QHash or std::map, + since Qt D-Bus provides generic templates to do the job of marshalling + the data. \sa endMap(), beginStructure(), beginArray(), beginMapEntry() */ diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h index 339f8c5dc8..f388a65bed 100644 --- a/src/dbus/qdbusargument.h +++ b/src/dbus/qdbusargument.h @@ -224,7 +224,8 @@ Q_DBUS_EXPORT const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &li Q_DBUS_EXPORT QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line); #endif -template<template <typename> class Container, typename T> +template<template <typename> class Container, typename T, + typename = typename Container<T>::iterator> inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<T> &list) { int id = qMetaTypeId<T>(); @@ -237,7 +238,8 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<T> &list) return arg; } -template<template <typename> class Container, typename T> +template<template <typename> class Container, typename T, + typename = typename Container<T>::iterator> inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &list) { arg.beginArray(); @@ -252,35 +254,6 @@ inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &l return arg; } -// QList specializations -template<typename T> -inline QDBusArgument &operator<<(QDBusArgument &arg, const QList<T> &list) -{ - int id = qMetaTypeId<T>(); - arg.beginArray(id); - typename QList<T>::ConstIterator it = list.constBegin(); - typename QList<T>::ConstIterator end = list.constEnd(); - for ( ; it != end; ++it) - arg << *it; - arg.endArray(); - return arg; -} - -template<typename T> -inline const QDBusArgument &operator>>(const QDBusArgument &arg, QList<T> &list) -{ - arg.beginArray(); - list.clear(); - while (!arg.atEnd()) { - T item; - arg >> item; - list.push_back(item); - } - arg.endArray(); - - return arg; -} - inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list) { int id = qMetaTypeId<QDBusVariant>(); @@ -293,15 +266,16 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list) return arg; } -// QMap specializations -template<typename Key, typename T> -inline QDBusArgument &operator<<(QDBusArgument &arg, const QMap<Key, T> &map) +// Specializations for associative containers +template <template <typename, typename> class Container, typename Key, typename T, + QtPrivate::IfAssociativeIteratorHasKeyAndValue<typename Container<Key, T>::iterator> = true> +inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<Key, T> &map) { int kid = qMetaTypeId<Key>(); int vid = qMetaTypeId<T>(); arg.beginMap(kid, vid); - typename QMap<Key, T>::ConstIterator it = map.constBegin(); - typename QMap<Key, T>::ConstIterator end = map.constEnd(); + auto it = map.begin(); + auto end = map.end(); for ( ; it != end; ++it) { arg.beginMapEntry(); arg << it.key() << it.value(); @@ -311,8 +285,27 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QMap<Key, T> &map) return arg; } -template<typename Key, typename T> -inline const QDBusArgument &operator>>(const QDBusArgument &arg, QMap<Key, T> &map) +template <template <typename, typename> class Container, typename Key, typename T, + QtPrivate::IfAssociativeIteratorHasFirstAndSecond<typename Container<Key, T>::iterator> = true> +inline QDBusArgument &operator<<(QDBusArgument &arg, const Container<Key, T> &map) +{ + int kid = qMetaTypeId<Key>(); + int vid = qMetaTypeId<T>(); + arg.beginMap(kid, vid); + auto it = map.begin(); + auto end = map.end(); + for ( ; it != end; ++it) { + arg.beginMapEntry(); + arg << it->first << it->second; + arg.endMapEntry(); + } + arg.endMap(); + return arg; +} + +template <template <typename, typename> class Container, typename Key, typename T, + typename = typename Container<Key, T>::iterator> +inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<Key, T> &map) { arg.beginMap(); map.clear(); @@ -321,7 +314,7 @@ inline const QDBusArgument &operator>>(const QDBusArgument &arg, QMap<Key, T> &m T value; arg.beginMapEntry(); arg >> key >> value; - static_cast<QMultiMap<Key, T> &>(map).insert(key, value); + map.insert(key, value); arg.endMapEntry(); } arg.endMap(); @@ -342,41 +335,6 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantMap &map) return arg; } -// QHash specializations -template<typename Key, typename T> -inline QDBusArgument &operator<<(QDBusArgument &arg, const QHash<Key, T> &map) -{ - int kid = qMetaTypeId<Key>(); - int vid = qMetaTypeId<T>(); - arg.beginMap(kid, vid); - typename QHash<Key, T>::ConstIterator it = map.constBegin(); - typename QHash<Key, T>::ConstIterator end = map.constEnd(); - for ( ; it != end; ++it) { - arg.beginMapEntry(); - arg << it.key() << it.value(); - arg.endMapEntry(); - } - arg.endMap(); - return arg; -} - -template<typename Key, typename T> -inline const QDBusArgument &operator>>(const QDBusArgument &arg, QHash<Key, T> &map) -{ - arg.beginMap(); - map.clear(); - while (!arg.atEnd()) { - Key key; - T value; - arg.beginMapEntry(); - arg >> key >> value; - static_cast<QMultiHash<Key, T> &>(map).insert(key, value); - arg.endMapEntry(); - } - arg.endMap(); - return arg; -} - inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantHash &map) { arg.beginMap(QMetaType::QString, qMetaTypeId<QDBusVariant>()); |