mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-06 10:15:38 +08:00
refs #876 All metaclass mixins now directly access the metamembers.
This avoids bloating CMetaClassIntrospector with inconvenient convenience methods.
This commit is contained in:
@@ -57,7 +57,7 @@ namespace BlackMisc
|
||||
{
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForComparison>());
|
||||
bool result = baseEquals(static_cast<const TBaseOfT<Derived> *>(&a), static_cast<const TBaseOfT<Derived> *>(&b));
|
||||
meta.forEachMemberPair(a, b, [ & ](auto &&... args) { result = result && EqualsByMetaClass::membersEqual(std::forward<decltype(args)>(args)...); });
|
||||
meta.forEachMember([ & ](auto member) { result = result && EqualsByMetaClass::membersEqual(member.in(a), member.in(b), member.m_flags); });
|
||||
return result;
|
||||
}
|
||||
template <typename T> static bool baseEquals(const T *a, const T *b) { return *a == *b; }
|
||||
@@ -122,7 +122,7 @@ namespace BlackMisc
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForComparison>());
|
||||
bool result = baseLess(static_cast<const TBaseOfT<Derived> *>(&a), static_cast<const TBaseOfT<Derived> *>(&b));
|
||||
bool gt = baseLess(static_cast<const TBaseOfT<Derived> *>(&b), static_cast<const TBaseOfT<Derived> *>(&a));
|
||||
meta.forEachMemberPair(a, b, [ & ](auto &&... args) { result = result || LessThanByMetaClass::membersLess(gt, std::forward<decltype(args)>(args)...); });
|
||||
meta.forEachMember([ & ](auto member) { result = result || LessThanByMetaClass::membersLess(gt, member.in(a), member.in(b), member.m_flags); });
|
||||
return result;
|
||||
}
|
||||
template <typename T> static bool baseLess(const T *a, const T *b) { return *a < *b; }
|
||||
@@ -158,7 +158,7 @@ namespace BlackMisc
|
||||
{
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForComparison>());
|
||||
int result = baseCompare(static_cast<const TBaseOfT<Derived> *>(&a), static_cast<const TBaseOfT<Derived> *>(&b));
|
||||
meta.forEachMemberPair(a, b, [ & ](auto &&... args) { result = result ? result : CompareByMetaClass::membersCompare(std::forward<decltype(args)>(args)...); });
|
||||
meta.forEachMember([ & ](auto member) { result = result ? result : CompareByMetaClass::membersCompare(member.in(a), member.in(b), member.m_flags); });
|
||||
return result;
|
||||
}
|
||||
template <typename T> static int baseCompare(const T *a, const T *b) { return compare(*a, *b); }
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace BlackMisc
|
||||
{
|
||||
baseMarshall(static_cast<const TBaseOfT<Derived> *>(derived()), arg);
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
||||
meta.forEachMember(*derived(), [ & ](const auto &member) { Private::marshallMember(arg, member); });
|
||||
meta.forEachMember([ &, this ](auto member) { Private::marshallMember(arg, member.in(*derived())); });
|
||||
}
|
||||
|
||||
//! Unmarshall without begin/endStructure, for when composed within another object
|
||||
@@ -92,7 +92,7 @@ namespace BlackMisc
|
||||
{
|
||||
baseUnmarshall(static_cast<TBaseOfT<Derived> *>(derived()), arg);
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
||||
meta.forEachMember(*derived(), [ & ](auto &member) { Private::unmarshallMember(arg, member); });
|
||||
meta.forEachMember([ &, this ](auto member) { Private::unmarshallMember(arg, member.in(*derived())); });
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -72,10 +72,12 @@ namespace BlackMisc
|
||||
};
|
||||
|
||||
// Work around MSVC2015 bug affecting generic lambda
|
||||
template <typename T>
|
||||
struct Hasher
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(const T &object) { m_hash ^= qHash(object); }
|
||||
template <typename U>
|
||||
void operator()(const U &member) { m_hash ^= qHash(member.in(m_object)); }
|
||||
const T &m_object;
|
||||
uint &m_hash;
|
||||
};
|
||||
|
||||
@@ -496,7 +498,7 @@ namespace BlackMisc
|
||||
{
|
||||
uint hash = baseHash(static_cast<const TBaseOfT<Derived> *>(&value));
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForHashing>());
|
||||
meta.forEachMember(value, Private::Hasher { hash });
|
||||
meta.forEachMember(Private::Hasher<Derived> { value, hash });
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
@@ -355,9 +355,9 @@ namespace BlackMisc
|
||||
{
|
||||
QJsonObject json;
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForJson>());
|
||||
meta.forEachMemberName(*derived(), [ & ](const auto & member, CExplicitLatin1String name)
|
||||
meta.forEachMember([ &, this ](auto member)
|
||||
{
|
||||
json << std::make_pair(name.toJsonKey(), std::cref(member));
|
||||
json << std::make_pair(CExplicitLatin1String(member.latin1Name()).toJsonKey(), std::cref(member.in(*derived())));
|
||||
});
|
||||
return Json::appendJsonObject(json, baseToJson(static_cast<const TBaseOfT<Derived> *>(derived())));
|
||||
}
|
||||
@@ -374,18 +374,18 @@ namespace BlackMisc
|
||||
{
|
||||
baseConvertFromJson(static_cast<TBaseOfT<Derived> *>(derived()), json);
|
||||
auto meta = introspect<Derived>().without(MetaFlags<DisabledForJson>());
|
||||
meta.forEachMemberName(*derived(), [ & ](auto & member, CExplicitLatin1String name)
|
||||
meta.forEachMember([ &, this ](auto member)
|
||||
{
|
||||
const auto value = json.value(name);
|
||||
const auto value = json.value(CExplicitLatin1String(member.latin1Name()));
|
||||
if (value.isUndefined())
|
||||
{
|
||||
constexpr bool required = false; //! \fixme add RequiredForJson flag in metaclass system
|
||||
if (required) { throw CJsonException(QStringLiteral("Missing required member '%1'").arg(name.m_latin1)); }
|
||||
if (required) { throw CJsonException(QStringLiteral("Missing required member '%1'").arg(member.latin1Name())); }
|
||||
}
|
||||
else
|
||||
{
|
||||
CJsonScope scope(name.m_latin1);
|
||||
value >> member;
|
||||
CJsonScope scope(member.latin1Name());
|
||||
value >> member.in(*derived());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -223,57 +223,16 @@ namespace BlackMisc
|
||||
template <typename Flags>
|
||||
static auto without(Flags) { return filter(MaskSequence<(! members().at(index<Is>()).has(Flags()))...>()); }
|
||||
|
||||
//! For each member in object, pass member as argument to visitor function.
|
||||
//! @{
|
||||
//! For each metamember in metaclass, pass metamember as argument to visitor function.
|
||||
template <typename F>
|
||||
static void forEachMember(T &object, F &&visitor)
|
||||
static void forEachMember(F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto) { std::forward<F>(visitor)(member.in(object)); });
|
||||
// parameter pack swallow idiom
|
||||
static_cast<void>(std::initializer_list<int>
|
||||
{
|
||||
(static_cast<void>(std::forward<F>(visitor)(members().at(index<Is>()))), 0)...
|
||||
});
|
||||
}
|
||||
template <typename F>
|
||||
static void forEachMember(const T &object, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto) { std::forward<F>(visitor)(member.in(object)); });
|
||||
}
|
||||
//! @}
|
||||
|
||||
//! For each member in object pair, pass member pair as arguments to visitor function.
|
||||
//! @{
|
||||
template <typename F>
|
||||
static void forEachMemberPair(T &left, T &right, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto flags) { std::forward<F>(visitor)(member.in(left), member.in(right), flags); });
|
||||
}
|
||||
template <typename F>
|
||||
static void forEachMemberPair(const T &left, T &right, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto flags) { std::forward<F>(visitor)(member.in(left), member.in(right), flags); });
|
||||
}
|
||||
template <typename F>
|
||||
static void forEachMemberPair(T &left, const T &right, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto flags) { std::forward<F>(visitor)(member.in(left), member.in(right), flags); });
|
||||
}
|
||||
template <typename F>
|
||||
static void forEachMemberPair(const T &left, const T &right, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto flags) { std::forward<F>(visitor)(member.in(left), member.in(right), flags); });
|
||||
}
|
||||
//! @}
|
||||
|
||||
//! For each member in object, pass member and its name as arguments to visitor function.
|
||||
//! @{
|
||||
template <typename F>
|
||||
static void forEachMemberName(T &object, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto) { std::forward<F>(visitor)(member.in(object), member.latin1Name()); });
|
||||
}
|
||||
template <typename F>
|
||||
static void forEachMemberName(const T &object, F &&visitor)
|
||||
{
|
||||
forEachImpl([ & ](auto &&member, auto) { std::forward<F>(visitor)(member.in(object), member.latin1Name()); });
|
||||
}
|
||||
//! @}
|
||||
|
||||
private:
|
||||
template <bool... Mask>
|
||||
@@ -286,16 +245,6 @@ namespace BlackMisc
|
||||
using index = std::integral_constant<size_t, I>;
|
||||
|
||||
constexpr static auto members() BLACK_TRAILING_RETURN(MetaClass::getMemberList()) { return MetaClass::getMemberList(); }
|
||||
|
||||
template <typename F>
|
||||
static void forEachImpl(F &&visitor)
|
||||
{
|
||||
// parameter pack swallow idiom
|
||||
static_cast<void>(std::initializer_list<int>
|
||||
{
|
||||
(static_cast<void>(std::forward<F>(visitor)(members().at(index<Is>()), MetaFlags<members().at(index<Is>()).m_flags>())), 0)...
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
namespace Private
|
||||
|
||||
@@ -106,10 +106,10 @@ namespace BlackMisc
|
||||
{
|
||||
QJsonObject json;
|
||||
auto meta = introspect<CAircraftModel>().without(MetaFlags<DisabledForJson>());
|
||||
meta.forEachMemberName(*this, [ & ](const auto & member, CExplicitLatin1String name)
|
||||
meta.forEachMember([ &, this ](auto member)
|
||||
{
|
||||
auto &&maybeMemo = helper.maybeMemoize(member);
|
||||
json << std::make_pair(name.toJsonKey(), std::cref(maybeMemo));
|
||||
auto &&maybeMemo = helper.maybeMemoize(member.in(*this));
|
||||
json << std::make_pair(CExplicitLatin1String(member.latin1Name()).toJsonKey(), std::cref(maybeMemo));
|
||||
});
|
||||
return json;
|
||||
}
|
||||
@@ -117,10 +117,10 @@ namespace BlackMisc
|
||||
void CAircraftModel::convertFromMemoizedJson(const QJsonObject &json, const MemoHelper::CUnmemoizer &helper)
|
||||
{
|
||||
auto meta = introspect<CAircraftModel>().without(MetaFlags<DisabledForJson>());
|
||||
meta.forEachMemberName(*this, [ & ](auto & member, CExplicitLatin1String name)
|
||||
meta.forEachMember([ &, this ](auto member)
|
||||
{
|
||||
auto it = json.find(name);
|
||||
if (it != json.end()) { it.value() >> helper.maybeUnmemoize(member).get(); }
|
||||
auto it = json.find(CExplicitLatin1String(member.latin1Name()));
|
||||
if (it != json.end()) { it.value() >> helper.maybeUnmemoize(member.in(*this)).get(); }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user