mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-03 15:45:46 +08:00
refs #345 Added a metatuple flag for case insensitive comparisons, so CAirportIcao and CCallsign comparisons can use metatuples.
This commit is contained in:
@@ -27,7 +27,7 @@ namespace BlackMisc
|
||||
int CAirportIcao::compareImpl(const CValueObject &otherBase) const
|
||||
{
|
||||
const auto &other = static_cast<const CAirportIcao &>(otherBase);
|
||||
return this->m_icaoCode.compare(other.m_icaoCode, Qt::CaseInsensitive);
|
||||
return compare(TupleConverter<CAirportIcao>::toMetaTuple(*this), TupleConverter<CAirportIcao>::toMetaTuple(other));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -96,7 +96,7 @@ namespace BlackMisc
|
||||
bool CAirportIcao::operator ==(const CAirportIcao &other) const
|
||||
{
|
||||
if (this == &other) return true;
|
||||
return this->asString().compare(other.asString(), Qt::CaseInsensitive) == 0;
|
||||
return TupleConverter<CAirportIcao>::toMetaTuple(*this) == TupleConverter<CAirportIcao>::toMetaTuple(other);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -106,7 +106,9 @@ namespace BlackMisc
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAirportIcao, (o.m_icaoCode))
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CAirportIcao, (
|
||||
attr(o.m_icaoCode, flags<CaseInsensitiveComparison>())
|
||||
))
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAirportIcao)
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace BlackMisc
|
||||
int CCallsign::compareImpl(const CValueObject &otherBase) const
|
||||
{
|
||||
const auto &other = static_cast<const CCallsign &>(otherBase);
|
||||
return this->m_callsign.compare(other.m_callsign, Qt::CaseInsensitive);
|
||||
return compare(TupleConverter<CCallsign>::toMetaTuple(*this), TupleConverter<CCallsign>::toMetaTuple(other));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -181,7 +181,7 @@ namespace BlackMisc
|
||||
bool CCallsign::operator ==(const CCallsign &other) const
|
||||
{
|
||||
if (this == &other) return true;
|
||||
return this->asString().compare(other.asString(), Qt::CaseInsensitive) == 0;
|
||||
return TupleConverter<CCallsign>::toMetaTuple(*this) == TupleConverter<CCallsign>::toMetaTuple(other);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -139,7 +139,11 @@ namespace BlackMisc
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CCallsign, (o.m_callsign, o.m_callsignAsSet, o.m_telephonyDesignator))
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::Aviation::CCallsign, (
|
||||
attr(o.m_callsign, flags<CaseInsensitiveComparison>()),
|
||||
attr(o.m_callsignAsSet, flags<DisabledForComparison>()),
|
||||
attr(o.m_telephonyDesignator, flags<DisabledForComparison>())
|
||||
))
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CCallsign)
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -26,7 +26,8 @@ namespace BlackMisc
|
||||
DisabledForMarshalling = 1 << 1, //!< Element will be ignored during DBus marshalling
|
||||
DisabledForDebugging = 1 << 2, //!< Element will be ignored when streaming to QDebug
|
||||
DisabledForHashing = 1 << 3, //!< Element will be ignored by qHash()
|
||||
DisabledForJson = 1 << 4 //!< Element will be ignored during JSON serialization
|
||||
DisabledForJson = 1 << 4, //!< Element will be ignored during JSON serialization
|
||||
CaseInsensitiveComparison = 1 << 5 //!< Element will be compared case insensitively (must be a QString)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -305,10 +306,9 @@ namespace BlackMisc
|
||||
template <class... Ts>
|
||||
int compare(std::tuple<Ts...> a, std::tuple<Ts...> b)
|
||||
{
|
||||
auto valuesA = Private::stripMeta(a, Private::make_index_sequence<sizeof...(Ts)>());
|
||||
auto valuesB = Private::stripMeta(b, Private::make_index_sequence<sizeof...(Ts)>());
|
||||
auto metaTu = Private::recoverMeta(a, Private::make_index_sequence<sizeof...(Ts)>());
|
||||
return Private::TupleHelper::compare(valuesA, valuesB, Private::skipFlaggedIndices<DisabledForComparison>(metaTu));
|
||||
auto metaA = Private::recoverMeta(a, Private::make_index_sequence<sizeof...(Ts)>());
|
||||
auto metaB = Private::recoverMeta(b, Private::make_index_sequence<sizeof...(Ts)>());
|
||||
return Private::TupleHelper::compare_(metaA, metaB, Private::skipFlaggedIndices<DisabledForComparison>(metaA));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -116,9 +116,47 @@ namespace BlackMisc
|
||||
return {};
|
||||
}
|
||||
|
||||
// CRTP base class for Attribute, to select appropriate method of comparison.
|
||||
template <class Derived, bool AlwaysEqual, bool CaseInsensitive>
|
||||
struct AttributeComparable;
|
||||
template <class Derived, bool CaseInsensitive>
|
||||
struct AttributeComparable<Derived, true, CaseInsensitive>
|
||||
{
|
||||
friend int compare(const Derived &, const Derived &) { return 0; }
|
||||
friend bool operator ==(const Derived &, const Derived &) { return true; }
|
||||
friend bool operator !=(const Derived &, const Derived &) { return false; }
|
||||
friend bool operator <(const Derived &, const Derived &) { return false; }
|
||||
friend bool operator <=(const Derived &, const Derived &) { return true; }
|
||||
friend bool operator >(const Derived &, const Derived &) { return false; }
|
||||
friend bool operator >=(const Derived &, const Derived &) { return true; }
|
||||
};
|
||||
template <class Derived>
|
||||
struct AttributeComparable<Derived, false, false>
|
||||
{
|
||||
template <class T> using isCValueObject = typename std::is_base_of<CValueObject, T>::type;
|
||||
friend int compare(const Derived &a, const Derived &b) { return compareHelper(a.m_obj, b.m_obj, isCValueObject<decltype(a.m_obj)>()); }
|
||||
friend bool operator ==(const Derived &a, const Derived &b) { return a.m_obj == b.m_obj; }
|
||||
friend bool operator !=(const Derived &a, const Derived &b) { return a.m_obj != b.m_obj; }
|
||||
friend bool operator <(const Derived &a, const Derived &b) { return a.m_obj < b.m_obj; }
|
||||
friend bool operator <=(const Derived &a, const Derived &b) { return a.m_obj <= b.m_obj; }
|
||||
friend bool operator >(const Derived &a, const Derived &b) { return a.m_obj > b.m_obj; }
|
||||
friend bool operator >=(const Derived &a, const Derived &b) { return a.m_obj >= b.m_obj; }
|
||||
};
|
||||
template <class Derived>
|
||||
struct AttributeComparable<Derived, false, true>
|
||||
{
|
||||
friend int compare(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive); }
|
||||
friend bool operator ==(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive) == 0; }
|
||||
friend bool operator !=(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive) != 0; }
|
||||
friend bool operator <(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive) < 0; }
|
||||
friend bool operator <=(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive) <= 0; }
|
||||
friend bool operator >(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive) > 0; }
|
||||
friend bool operator >=(const Derived &a, const Derived &b) { return a.m_obj.compare(b.m_obj, Qt::CaseInsensitive) >= 0; }
|
||||
};
|
||||
|
||||
// A tuple element with attached metadata.
|
||||
template <class T, qint64 Flags = 0>
|
||||
struct Attribute
|
||||
struct Attribute : public AttributeComparable<Attribute<T, Flags>, Flags & DisabledForComparison, Flags & CaseInsensitiveComparison>
|
||||
{
|
||||
typedef T type;
|
||||
static const qint64 flags = Flags;
|
||||
@@ -127,13 +165,6 @@ namespace BlackMisc
|
||||
void extend(QString jsonName) { if (m_jsonName.isEmpty()) m_jsonName = jsonName; }
|
||||
T &m_obj;
|
||||
QString m_jsonName;
|
||||
|
||||
friend bool operator ==(const Attribute &a, const Attribute &b) { return a.m_obj == b.m_obj; }
|
||||
friend bool operator !=(const Attribute &a, const Attribute &b) { return a.m_obj != b.m_obj; }
|
||||
friend bool operator <(const Attribute &a, const Attribute &b) { return a.m_obj < b.m_obj; }
|
||||
friend bool operator <=(const Attribute &a, const Attribute &b) { return a.m_obj <= b.m_obj; }
|
||||
friend bool operator >(const Attribute &a, const Attribute &b) { return a.m_obj > b.m_obj; }
|
||||
friend bool operator >=(const Attribute &a, const Attribute &b) { return a.m_obj >= b.m_obj; }
|
||||
};
|
||||
|
||||
// Helpers used in tie(), tieMeta(), and elsewhere, which arrange for the correct types to be passed to std::make_tuple.
|
||||
@@ -193,9 +224,9 @@ namespace BlackMisc
|
||||
{
|
||||
public:
|
||||
template <class Tu, size_t... Is>
|
||||
static int compare(const Tu &a, const Tu &b, index_sequence<Is...>)
|
||||
static int compare_(const Tu &a, const Tu &b, index_sequence<Is...>) // underscore to avoid hiding the name "compare" in other scopes
|
||||
{
|
||||
return compareImpl(std::make_pair(get_ref<Is>(a), get_ref<Is>(b))...);
|
||||
return compareImpl(std::make_pair(std::get<Is>(a), std::get<Is>(b))...);
|
||||
}
|
||||
|
||||
template <class Tu, size_t... Is>
|
||||
@@ -260,7 +291,7 @@ namespace BlackMisc
|
||||
template <class T, class... Ts>
|
||||
static int compareImpl(const std::pair<T, T> &head, const Ts &... tail)
|
||||
{
|
||||
int result = compareHelper(head.first, head.second, typename std::is_base_of<CValueObject, typename std::decay<T>::type>::type());
|
||||
int result = compare(head.first, head.second);
|
||||
if (result) return result;
|
||||
return compareImpl(tail...);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user