From 9d1f8a63f3a564841a4c38318cfa624d88b9ce53 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 26 Mar 2014 18:02:36 +0100 Subject: [PATCH] refs #192 , added JSON support to tupel * jsonMembers() method in Macro * serializeJson / deserializeJson for tupels --- src/blackmisc/tuple.h | 340 +++++++++++++++++++++++++++++++--- src/blackmisc/tuple_private.h | 54 ++++-- 2 files changed, 359 insertions(+), 35 deletions(-) diff --git a/src/blackmisc/tuple.h b/src/blackmisc/tuple.h index a5bd2d373..21f84687e 100644 --- a/src/blackmisc/tuple.h +++ b/src/blackmisc/tuple.h @@ -11,6 +11,7 @@ #define BLACKMISC_TUPLE_H #include "tuple_private.h" +#include "json.h" /*! * \defgroup Tuples Tuples Simplified handling of class members (CValueObject) by std::tuple @@ -49,7 +50,7 @@ { \ friend class T; \ static_assert(Private::HasEnabledTupleConversion::type::value, \ - "Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \ + "Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \ static auto toTuple(const T &o) -> decltype(std::tie MEMBERS) \ { \ return std::tie MEMBERS; \ @@ -58,6 +59,11 @@ { \ return std::tie MEMBERS; \ } \ + static const QStringList &jsonMembers() \ + { \ + static QStringList members = QString(#MEMBERS).replace("(","").replace(")","").replace(" ","").replace("o.","").split(","); \ + return members; \ + } \ }; \ } @@ -73,7 +79,7 @@ { \ friend class T; \ static_assert(Private::HasEnabledTupleConversion>::type::value,\ - "Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \ + "Missing BLACK_ENABLE_TUPLE_CONVERSION macro in " #T); \ static auto toTuple(const T &o) -> decltype(std::tie MEMBERS) \ { \ return std::tie MEMBERS; \ @@ -82,6 +88,11 @@ { \ return std::tie MEMBERS; \ } \ + static const QStringList &jsonMembers() \ + { \ + static QStringList members = QString(#MEMBERS).replace("(","").replace(")","").replace(" ","").replace("o.","").split(","); \ + return members; \ + } \ }; \ } @@ -113,17 +124,31 @@ namespace BlackMisc static std::tuple<> toTuple(const T &object) { static_assert(std::is_void::value, // always false; is_void<> trick is just to make the condition dependent on the template parameter T - "Missing BLACK_DECLARE_TUPLE_CONVERSION macro for T"); + "Missing BLACK_DECLARE_TUPLE_CONVERSION macro for T"); Q_UNUSED(object); return std::tuple<>(); } static std::tuple<> toTuple(T &object) { static_assert(std::is_void::value, // always false; is_void<> trick is just to make the condition dependent on the template parameter T - "Missing BLACK_DECLARE_TUPLE_CONVERSION macro for T"); + "Missing BLACK_DECLARE_TUPLE_CONVERSION macro for T"); Q_UNUSED(object); return std::tuple<>(); } + static const QStringList members() + { + static_assert(std::is_void::value, // always false; is_void<> trick is just to make the condition dependent on the template parameter T + "Missing BLACK_DECLARE_TUPLE_CONVERSION macro for T"); + static QStringList members; + return members; + } + static const QStringList jsonMembers() + { + static_assert(std::is_void::value, // always false; is_void<> trick is just to make the condition dependent on the template parameter T + "Missing BLACK_DECLARE_TUPLE_CONVERSION macro for T"); + static QStringList members; + return members; + } //! @} }; @@ -176,6 +201,29 @@ namespace BlackMisc return Private::TupleHelper::hash(tu); } + /*! + * \brief Convert to a JSON object + * \ingroup Tupels + */ + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + Private::TupleHelper::serializeJson(json, members, tu); + return json; + } + + /*! + * Convert from JSON to object + * \ingroup Tupels + */ + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + Private::TupleHelper::deserializeJson(json, members, tu); + } + + #else // !Q_COMPILER_VARIADIC_TEMPLATES inline int compare(std::tuple<>, std::tuple<>) @@ -336,35 +384,35 @@ namespace BlackMisc QDBusArgument &operator <<(QDBusArgument &arg, std::tuple tu) { return arg << std::get<0>(tu) << std::get<1>(tu) << std::get<2>(tu) << std::get<3>(tu) << std::get<4>(tu) - << std::get<5>(tu); + << std::get<5>(tu); } template QDBusArgument &operator <<(QDBusArgument &arg, std::tuple tu) { return arg << std::get<0>(tu) << std::get<1>(tu) << std::get<2>(tu) << std::get<3>(tu) << std::get<4>(tu) - << std::get<5>(tu) << std::get<6>(tu); + << std::get<5>(tu) << std::get<6>(tu); } template QDBusArgument &operator <<(QDBusArgument &arg, std::tuple tu) { return arg << std::get<0>(tu) << std::get<1>(tu) << std::get<2>(tu) << std::get<3>(tu) << std::get<4>(tu) - << std::get<5>(tu) << std::get<6>(tu) << std::get<7>(tu); + << std::get<5>(tu) << std::get<6>(tu) << std::get<7>(tu); } template QDBusArgument &operator <<(QDBusArgument &arg, std::tuple tu) { return arg << std::get<0>(tu) << std::get<1>(tu) << std::get<2>(tu) << std::get<3>(tu) << std::get<4>(tu) - << std::get<5>(tu) << std::get<6>(tu) << std::get<7>(tu) << std::get<8>(tu); + << std::get<5>(tu) << std::get<6>(tu) << std::get<7>(tu) << std::get<8>(tu); } template QDBusArgument &operator <<(QDBusArgument &arg, std::tuple tu) { return arg << std::get<0>(tu) << std::get<1>(tu) << std::get<2>(tu) << std::get<3>(tu) << std::get<4>(tu) - << std::get<5>(tu) << std::get<6>(tu) << std::get<7>(tu) << std::get<8>(tu) << std::get<9>(tu); + << std::get<5>(tu) << std::get<6>(tu) << std::get<7>(tu) << std::get<8>(tu) << std::get<9>(tu); } inline const QDBusArgument &operator >>(const QDBusArgument &arg, std::tuple<>) @@ -406,35 +454,147 @@ namespace BlackMisc const QDBusArgument &operator >>(const QDBusArgument &arg, std::tuple tu) { return arg >> std::get<0>(tu) >> std::get<1>(tu) >> std::get<2>(tu) >> std::get<3>(tu) >> std::get<4>(tu) - >> std::get<5>(tu); + >> std::get<5>(tu); } template const QDBusArgument &operator >>(const QDBusArgument &arg, std::tuple tu) { return arg >> std::get<0>(tu) >> std::get<1>(tu) >> std::get<2>(tu) >> std::get<3>(tu) >> std::get<4>(tu) - >> std::get<5>(tu) >> std::get<6>(tu); + >> std::get<5>(tu) >> std::get<6>(tu); } template const QDBusArgument &operator >>(const QDBusArgument &arg, std::tuple tu) { return arg >> std::get<0>(tu) >> std::get<1>(tu) >> std::get<2>(tu) >> std::get<3>(tu) >> std::get<4>(tu) - >> std::get<5>(tu) >> std::get<6>(tu) >> std::get<7>(tu); + >> std::get<5>(tu) >> std::get<6>(tu) >> std::get<7>(tu); } template const QDBusArgument &operator >>(const QDBusArgument &arg, std::tuple tu) { return arg >> std::get<0>(tu) >> std::get<1>(tu) >> std::get<2>(tu) >> std::get<3>(tu) >> std::get<4>(tu) - >> std::get<5>(tu) >> std::get<6>(tu) >> std::get<7>(tu) >> std::get<8>(tu); + >> std::get<5>(tu) >> std::get<6>(tu) >> std::get<7>(tu) >> std::get<8>(tu); } template const QDBusArgument &operator >>(const QDBusArgument &arg, std::tuple tu) { return arg >> std::get<0>(tu) >> std::get<1>(tu) >> std::get<2>(tu) >> std::get<3>(tu) >> std::get<4>(tu) - >> std::get<5>(tu) >> std::get<6>(tu) >> std::get<7>(tu) >> std::get<8>(tu) >> std::get<9>(tu); + >> std::get<5>(tu) >> std::get<6>(tu) >> std::get<7>(tu) >> std::get<8>(tu) >> std::get<9>(tu); + } + + inline void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple<> tu) + { + Q_UNUSED(json); + Q_UNUSED(members); + Q_UNUSED(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + json.value(members.at(4)) >> std::get<4>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + json.value(members.at(4)) >> std::get<4>(tu); + json.value(members.at(5)) >> std::get<5>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + json.value(members.at(4)) >> std::get<4>(tu); + json.value(members.at(5)) >> std::get<5>(tu); + json.value(members.at(6)) >> std::get<6>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + json.value(members.at(4)) >> std::get<4>(tu); + json.value(members.at(5)) >> std::get<5>(tu); + json.value(members.at(6)) >> std::get<6>(tu); + json.value(members.at(7)) >> std::get<7>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + json.value(members.at(4)) >> std::get<4>(tu); + json.value(members.at(5)) >> std::get<5>(tu); + json.value(members.at(6)) >> std::get<6>(tu); + json.value(members.at(7)) >> std::get<7>(tu); + json.value(members.at(8)) >> std::get<8>(tu); + } + + template + void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple tu) + { + json.value(members.at(0)) >> std::get<0>(tu); + json.value(members.at(1)) >> std::get<1>(tu); + json.value(members.at(2)) >> std::get<2>(tu); + json.value(members.at(3)) >> std::get<3>(tu); + json.value(members.at(4)) >> std::get<4>(tu); + json.value(members.at(5)) >> std::get<5>(tu); + json.value(members.at(6)) >> std::get<6>(tu); + json.value(members.at(7)) >> std::get<7>(tu); + json.value(members.at(8)) >> std::get<8>(tu); + json.value(members.at(9)) >> std::get<9>(tu); } inline uint qHash(std::tuple<>) @@ -475,36 +635,168 @@ namespace BlackMisc template uint qHash(std::tuple tu) { - return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) - ^ qHash(std::get<5>(tu)); + return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) ^ + qHash(std::get<5>(tu)); } template uint qHash(std::tuple tu) { - return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) - ^ qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)); + return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) ^ + qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)); } template uint qHash(std::tuple tu) { - return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) - ^ qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)) ^ qHash(std::get<7>(tu)); + return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) ^ + qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)) ^ qHash(std::get<7>(tu)); } template uint qHash(std::tuple tu) { - return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) - ^ qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)) ^ qHash(std::get<7>(tu)) ^ qHash(std::get<8>(tu)); + return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) ^ + qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)) ^ qHash(std::get<7>(tu)) ^ qHash(std::get<8>(tu)); } template uint qHash(std::tuple tu) { - return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) - ^ qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)) ^ qHash(std::get<7>(tu)) ^ qHash(std::get<8>(tu)) ^ qHash(std::get<9>(tu)); + return qHash(std::get<0>(tu)) ^ qHash(std::get<1>(tu)) ^ qHash(std::get<2>(tu)) ^ qHash(std::get<3>(tu)) ^ qHash(std::get<4>(tu)) ^ + qHash(std::get<5>(tu)) ^ qHash(std::get<6>(tu)) ^ qHash(std::get<7>(tu)) ^ qHash(std::get<8>(tu)) ^ qHash(std::get<9>(tu)); + } + + inline QJsonObject serializeJson(const QStringList &members, std::tuple<>) + { + Q_UNUSED(members); + QJsonObject json; + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + json << std::pair(members.at(4), std::get<4>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + json << std::pair(members.at(4), std::get<4>(tu)); + json << std::pair(members.at(5), std::get<5>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + json << std::pair(members.at(4), std::get<4>(tu)); + json << std::pair(members.at(5), std::get<5>(tu)); + json << std::pair(members.at(6), std::get<6>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + json << std::pair(members.at(4), std::get<4>(tu)); + json << std::pair(members.at(5), std::get<5>(tu)); + json << std::pair(members.at(6), std::get<6>(tu)); + json << std::pair(members.at(7), std::get<7>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + json << std::pair(members.at(4), std::get<4>(tu)); + json << std::pair(members.at(5), std::get<5>(tu)); + json << std::pair(members.at(6), std::get<6>(tu)); + json << std::pair(members.at(7), std::get<7>(tu)); + json << std::pair(members.at(8), std::get<8>(tu)); + return json; + } + + template + QJsonObject serializeJson(const QStringList &members, std::tuple tu) + { + QJsonObject json; + json << std::pair(members.at(0), std::get<0>(tu)); + json << std::pair(members.at(1), std::get<1>(tu)); + json << std::pair(members.at(2), std::get<2>(tu)); + json << std::pair(members.at(3), std::get<3>(tu)); + json << std::pair(members.at(4), std::get<4>(tu)); + json << std::pair(members.at(5), std::get<5>(tu)); + json << std::pair(members.at(6), std::get<6>(tu)); + json << std::pair(members.at(7), std::get<7>(tu)); + json << std::pair(members.at(8), std::get<8>(tu)); + json << std::pair(members.at(9), std::get<9>(tu)); + return json; } #endif // Q_COMPILER_VARIADIC_TEMPLATES diff --git a/src/blackmisc/tuple_private.h b/src/blackmisc/tuple_private.h index 7a911e0cd..2b7a01816 100644 --- a/src/blackmisc/tuple_private.h +++ b/src/blackmisc/tuple_private.h @@ -11,15 +11,17 @@ #ifndef BLACKMISC_TUPLE_PRIVATE_H #define BLACKMISC_TUPLE_PRIVATE_H +#include "json.h" #include #include #include +#include +#include #include #include namespace BlackMisc { - class CValueObject; namespace Private @@ -62,11 +64,11 @@ namespace BlackMisc template int compareHelper(const Tu &a, const Tu &b) { - typedef typename std::is_base_of< - CValueObject, - typename std::decay< - typename std::tuple_element::type - >::type + typedef typename std::is_base_of < + CValueObject, + typename std::decay < + typename std::tuple_element::type + >::type >::type isCValueObjectTag; return compareHelper(std::get(a), std::get(b), isCValueObjectTag()); @@ -83,27 +85,43 @@ namespace BlackMisc template static int compare(const Tu &a, const Tu &b) { - const int head = TupleHelper::compare(a, b); + const int head = TupleHelper < N - 1 >::compare(a, b); if (head) { return head; } - return compareHelper(a, b); + return compareHelper < N - 1 > (a, b); } template static QDBusArgument &marshall(QDBusArgument &arg, const Tu &tu) { - return TupleHelper::marshall(arg, tu) << std::get(tu); + return TupleHelper < N - 1 >::marshall(arg, tu) << std::get < N - 1 > (tu); } template static const QDBusArgument &unmarshall(const QDBusArgument &arg, Tu &tu) { - return TupleHelper::unmarshall(arg, tu) >> std::get(tu); + return TupleHelper < N - 1 >::unmarshall(arg, tu) >> std::get < N - 1 > (tu); } template static uint hash(const Tu &tu) { - return TupleHelper::hash(tu) ^ qHash(std::get(tu)); + return TupleHelper < N - 1 >::hash(tu) ^ qHash(std::get < N - 1 > (tu)); + } + + template + static void serializeJson(QJsonObject &json, const QStringList &members, const Tu &tu) + { + // typedef typename std::remove_const < typename std::remove_reference < typename std::tuple_element < N - 1, Tu >::type >::type >::type TARGET; + typedef typename std::decay < typename std::tuple_element < N - 1, Tu >::type >::type TARGET; + json << std::pair(members.at(N - 1), std::get < N - 1 > (tu)); + TupleHelper < N - 1 >::serializeJson(json, members, tu); + } + + template + static void deserializeJson(const QJsonObject &json, const QStringList &members, Tu &tu) + { + json.value(members.at(N - 1)) >> std::get < N - 1 > (tu); + TupleHelper < N - 1 >::deserializeJson(json, members, tu); } }; @@ -119,6 +137,20 @@ namespace BlackMisc static const QDBusArgument &unmarshall(const QDBusArgument &arg, Tu &) { return arg; } template static uint hash(const Tu &) { return 0; } + template + static void serializeJson(QJsonObject &json, const QStringList &members, const Tu &tu) + { + Q_UNUSED(json); + Q_UNUSED(members); + Q_UNUSED(tu); + } + template + static void deserializeJson(const QJsonObject &json, const QStringList &members, Tu &tu) + { + Q_UNUSED(json); + Q_UNUSED(members); + Q_UNUSED(tu); + } }; #endif // Q_COMPILER_VARIADIC_TEMPLATES