mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 17:35:34 +08:00
refs #698 Added equalsBy and equalsByKeys methods for containers.
This commit is contained in:
@@ -72,6 +72,26 @@ namespace BlackMisc
|
||||
template <class T> bool operator()(const T &a, const T &b) const { return head.isStable(a, b) ? head(a, b) : tail(a, b); }
|
||||
};
|
||||
|
||||
//! \private
|
||||
template <class...> struct EqualsByMembers;
|
||||
|
||||
//! \private
|
||||
template <class M> struct EqualsByMembers<M>
|
||||
{
|
||||
M m;
|
||||
EqualsByMembers(M m_) : m(m_) {}
|
||||
template <class T> bool operator()(const T &a, const T &b) const { return (a.*m)() == (b.*m)(); }
|
||||
};
|
||||
|
||||
//! \private
|
||||
template <class M, class... Tail> struct EqualsByMembers<M, Tail...>
|
||||
{
|
||||
EqualsByMembers<M> head;
|
||||
EqualsByMembers<Tail...> tail;
|
||||
EqualsByMembers(M m, Tail... tail_) : head(m), tail(tail_...) {}
|
||||
template <class T> bool operator()(const T &a, const T &b) const { return head(a, b) && tail(a, b); }
|
||||
};
|
||||
|
||||
//! \private
|
||||
struct Matches
|
||||
{
|
||||
@@ -141,6 +161,15 @@ namespace BlackMisc
|
||||
return [value = std::forward<T>(value)](const T &object) { return object == value; };
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns a predicate that returns true if its arguments compare equal to each other, considering only the captured members.
|
||||
*/
|
||||
template <class... Ts>
|
||||
Private::EqualsByMembers<Ts...> EqualsByMembers(Ts... vs)
|
||||
{
|
||||
return { vs... };
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns a predicate that returns true if its argument matches a captured CPropertyIndexVariantMap.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "iterator.h"
|
||||
#include "predicates.h"
|
||||
#include "algorithm.h"
|
||||
#include "typetraits.h"
|
||||
#include <QtGlobal>
|
||||
#include <QDebug>
|
||||
#include <algorithm>
|
||||
@@ -110,6 +111,21 @@ namespace BlackMisc
|
||||
return containsBy(BlackMisc::Predicates::MemberEqual(k0, v0, keysValues...));
|
||||
}
|
||||
|
||||
//! Return true if this container equals another container according to the given element equality predicate.
|
||||
template <class T, class Predicate>
|
||||
bool equalsBy(const T &other, Predicate c) const
|
||||
{
|
||||
if (equalPointers(&derived(), &other)) { return true; }
|
||||
return std::equal(derived().begin(), derived().end(), other.begin(), other.end(), c);
|
||||
}
|
||||
|
||||
//! Return true if this container equals another container, considering only the given element members.
|
||||
template <class T, class Key0, class... Keys>
|
||||
bool equalsByKeys(const T &other, Key0 k0, Keys... keys) const
|
||||
{
|
||||
return equalsBy(other, BlackMisc::Predicates::EqualsByMembers(k0, keys...));
|
||||
}
|
||||
|
||||
//! Copy n elements from the container at random.
|
||||
Derived randomElements(int n) const
|
||||
{
|
||||
@@ -126,6 +142,15 @@ namespace BlackMisc
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Efficiently compare addresses of two objects. Return false if types are not compatible.
|
||||
//! @{
|
||||
template <typename T, typename U, std::enable_if_t<IsEqualityComparable<const T *, const U *>::value, int> = 0>
|
||||
static bool equalPointers(const T *a, const U *b) { return a == b; }
|
||||
template <typename T, typename U, std::enable_if_t<! IsEqualityComparable<const T *, const U *>::value, int> = 0>
|
||||
static bool equalPointers(const T *, const U *) { return false; }
|
||||
//! @}
|
||||
|
||||
private:
|
||||
Derived &derived() { return static_cast<Derived &>(*this); }
|
||||
const Derived &derived() const { return static_cast<const Derived &>(*this); }
|
||||
|
||||
@@ -102,6 +102,16 @@ namespace BlackMisc
|
||||
struct HasCompare<T, U, void_t<decltype(compare(std::declval<T>(), std::declval<U>()))>> : public std::true_type {};
|
||||
//! \endcond
|
||||
|
||||
/*!
|
||||
* Trait which is true if the expression a == b is valid when a and b are instances of T and U.
|
||||
*/
|
||||
template <typename T, typename U, typename = void_t<>>
|
||||
struct IsEqualityComparable : public std::false_type {};
|
||||
//! \cond
|
||||
template <typename T, typename U>
|
||||
struct IsEqualityComparable<T, U, void_t<decltype(std::declval<T>() == std::declval<U>())>> : public std::true_type {};
|
||||
//! \endcond
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user