mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-02 06:35:52 +08:00
refs #210 added jsonName in Private::Attribute
* Explicit JSON name can be set for tuple members * Names can still be extracted by preprocessor stringification if not explicitly set * In both cases, names are embedded in Attribute metadata, so no need to call jsonMembers() in the value classes
This commit is contained in:
@@ -63,11 +63,13 @@
|
||||
static auto toMetaTuple(const T &o) -> decltype(BlackMisc::tieMeta MEMBERS) \
|
||||
{ \
|
||||
auto tu = BlackMisc::tieMeta MEMBERS; \
|
||||
parser().extendMetaTuple(tu); \
|
||||
return tu; \
|
||||
} \
|
||||
static auto toMetaTuple(T &o) -> decltype(BlackMisc::tieMeta MEMBERS) \
|
||||
{ \
|
||||
auto tu = BlackMisc::tieMeta MEMBERS; \
|
||||
parser().extendMetaTuple(tu); \
|
||||
return tu; \
|
||||
} \
|
||||
static const Parser &parser() \
|
||||
@@ -111,11 +113,13 @@
|
||||
static auto toMetaTuple(const T<U...> &o) -> decltype(BlackMisc::tieMeta MEMBERS) \
|
||||
{ \
|
||||
auto tu = BlackMisc::tieMeta MEMBERS; \
|
||||
parser().extendMetaTuple(tu); \
|
||||
return tu; \
|
||||
} \
|
||||
static auto toMetaTuple(T<U...> &o) -> decltype(BlackMisc::tieMeta MEMBERS) \
|
||||
{ \
|
||||
auto tu = BlackMisc::tieMeta MEMBERS; \
|
||||
parser().extendMetaTuple(tu); \
|
||||
return tu; \
|
||||
} \
|
||||
static const Parser &parser() \
|
||||
@@ -169,11 +173,23 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
//! \brief Create a tuple element with attached metadata.
|
||||
//! @{
|
||||
template <class T, quint64 F>
|
||||
static Private::Attribute<T, F> attr(T &obj, std::integral_constant<quint64, F>)
|
||||
{
|
||||
return { obj };
|
||||
}
|
||||
template <class T>
|
||||
static Private::Attribute<T> attr(T &obj, QString jsonName)
|
||||
{
|
||||
return { obj, jsonName };
|
||||
}
|
||||
template <class T, quint64 F>
|
||||
static Private::Attribute<T, F> attr(T &obj, QString jsonName, std::integral_constant<quint64, F>)
|
||||
{
|
||||
return { obj, jsonName };
|
||||
}
|
||||
//! @}
|
||||
|
||||
//! \brief Helper class which parses the stringified macro argument.
|
||||
struct Parser
|
||||
@@ -181,6 +197,14 @@ namespace BlackMisc
|
||||
Parser(QString); //!< Constructor.
|
||||
QStringList m_raw; //!< The raw macro argument, split by top-level commas.
|
||||
QStringList m_names; //!< The names of the tuple members, stripped of any o.m_ prefix.
|
||||
|
||||
//! Fills in any incomplete metadata in a tuple using information from the Parser.
|
||||
template <class Tu>
|
||||
void extendMetaTuple(Tu &&tu) const
|
||||
{
|
||||
Private::extendMeta(std::forward<Tu>(tu), m_names,
|
||||
Private::make_index_sequence<std::tuple_size<typename std::decay<Tu>::type>::value>());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -233,6 +257,7 @@ namespace BlackMisc
|
||||
/*!
|
||||
* \name Static Private Member Functions
|
||||
* \brief Returns a list of the names of the tuple members.
|
||||
* \deprecated This information is now embedded in the meta tuples.
|
||||
*/
|
||||
static const QStringList &jsonMembers();
|
||||
};
|
||||
@@ -339,6 +364,7 @@ namespace BlackMisc
|
||||
/*!
|
||||
* \brief Convert to a JSON object
|
||||
* \ingroup Tuples
|
||||
* \deprecated The QStringList members can be embedded in tuple metadata.
|
||||
*/
|
||||
template <class... Ts>
|
||||
QJsonObject serializeJson(const QStringList &members, std::tuple<Ts...> tu)
|
||||
@@ -353,6 +379,7 @@ namespace BlackMisc
|
||||
/*!
|
||||
* \brief Convert from JSON to object
|
||||
* \ingroup Tuples
|
||||
* \deprecated The QStringList members can be embedded in tuple metadata.
|
||||
*/
|
||||
template <class... Ts>
|
||||
void deserializeJson(const QJsonObject &json, const QStringList &members, std::tuple<Ts...> tu)
|
||||
@@ -362,6 +389,30 @@ namespace BlackMisc
|
||||
Private::TupleHelper::deserializeJson(json, members, valueTu, Private::skipFlaggedIndices<TupleConverterBase::DisabledForJson>(metaTu));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Convert to a JSON object
|
||||
* \ingroup Tuples
|
||||
*/
|
||||
template <class... Ts>
|
||||
QJsonObject serializeJson(std::tuple<Ts...> tu)
|
||||
{
|
||||
QJsonObject json;
|
||||
Private::assertMeta<std::tuple<Ts...>>();
|
||||
Private::TupleHelper::serializeJson(json, tu, Private::skipFlaggedIndices<TupleConverterBase::DisabledForJson>(tu));
|
||||
return json;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Convert from JSON to object
|
||||
* \ingroup Tuples
|
||||
*/
|
||||
template <class... Ts>
|
||||
void deserializeJson(const QJsonObject &json, std::tuple<Ts...> tu)
|
||||
{
|
||||
Private::assertMeta<std::tuple<Ts...>>();
|
||||
Private::TupleHelper::deserializeJson(json, tu, Private::skipFlaggedIndices<TupleConverterBase::DisabledForJson>(tu));
|
||||
}
|
||||
|
||||
} // namespace BlackMisc
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -138,8 +138,10 @@ namespace BlackMisc
|
||||
typedef T type;
|
||||
static const quint64 flags = Flags;
|
||||
|
||||
Attribute(T &obj) : m_obj(obj) {}
|
||||
Attribute(T &obj, QString jsonName = {}) : m_obj(obj), m_jsonName(jsonName) {}
|
||||
void extend(QString jsonName) { if (m_jsonName.isEmpty()) m_jsonName = jsonName; }
|
||||
T &m_obj;
|
||||
QString m_jsonName;
|
||||
|
||||
bool operator ==(const Attribute &other) const { return m_obj == other.m_obj; }
|
||||
bool operator !=(const Attribute &other) const { return m_obj != other.m_obj; }
|
||||
@@ -174,6 +176,12 @@ namespace BlackMisc
|
||||
return attr;
|
||||
}
|
||||
|
||||
// Compile-time assert for functions which require a meta tuple
|
||||
template <class Tu>
|
||||
struct assertMeta { static_assert(std::is_void<Tu>::value, "Function expected a meta tuple, got a value tuple"); };
|
||||
template <class... Ts, quint64... Fs>
|
||||
struct assertMeta<std::tuple<Attribute<Ts, Fs>...>> {};
|
||||
|
||||
// Convert a meta tuple to a value tuple
|
||||
template <class Tu, size_t... Is>
|
||||
auto stripMeta(Tu &&tu, index_sequence<Is...>) -> decltype(std::make_tuple(tieHelper(std::get<Is>(std::forward<Tu>(tu)))...))
|
||||
@@ -188,6 +196,13 @@ namespace BlackMisc
|
||||
return std::make_tuple(tieMetaHelper(std::get<Is>(std::forward<Tu>(tu)))...);
|
||||
}
|
||||
|
||||
// Fill in any incomplete metadata in a meta tuple, from an appropriate source
|
||||
template <class Tu, size_t... Is>
|
||||
void extendMeta(Tu &&tu, const QStringList &jsonNames, index_sequence<Is...>)
|
||||
{
|
||||
[](...){}((std::get<Is>(std::forward<Tu>(tu)).extend(jsonNames[Is]), 0)...);
|
||||
}
|
||||
|
||||
// Applying operations to all elements in a tuple, using index_sequence for clean recursion
|
||||
class TupleHelper
|
||||
{
|
||||
@@ -237,11 +252,23 @@ namespace BlackMisc
|
||||
deserializeJsonImpl(json, std::make_pair(names[Is], get_ref<Is>(tu))...);
|
||||
}
|
||||
|
||||
private:
|
||||
template <size_t I, class T>
|
||||
static auto get_ref(T &&tu) -> decltype(std::ref(std::get<I>(std::forward<T>(tu))))
|
||||
template <class Tu, size_t... Is>
|
||||
static void serializeJson(QJsonObject &json, const Tu &tu, index_sequence<Is...>)
|
||||
{
|
||||
return std::ref(std::get<I>(std::forward<T>(tu)));
|
||||
serializeJsonImpl(json, std::make_pair(std::get<Is>(tu).m_jsonName, std::get<Is>(tu).m_obj)...);
|
||||
}
|
||||
|
||||
template <class Tu, size_t... Is>
|
||||
static void deserializeJson(const QJsonObject &json, Tu &tu, index_sequence<Is...>)
|
||||
{
|
||||
deserializeJsonImpl(json, std::make_pair(std::get<Is>(tu).m_jsonName, get_ref<Is>(tu))...);
|
||||
}
|
||||
|
||||
private:
|
||||
template <size_t I, class Tu>
|
||||
static auto get_ref(Tu &&tu) -> decltype(tieHelper(std::get<I>(std::forward<Tu>(tu))))
|
||||
{
|
||||
return tieHelper(std::get<I>(std::forward<Tu>(tu)));
|
||||
}
|
||||
|
||||
static int compareImpl() { return 0; }
|
||||
|
||||
Reference in New Issue
Block a user