mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-17 02:45:33 +08:00
refs #700 Added sortByProperty method for sequences.
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include "blackmisc/json.h"
|
#include "blackmisc/json.h"
|
||||||
#include "blackmisc/metaclass.h"
|
#include "blackmisc/metaclass.h"
|
||||||
#include "blackmisc/stringutils.h"
|
#include "blackmisc/stringutils.h"
|
||||||
|
#include "blackmisc/typetraits.h"
|
||||||
#include "blackmisc/variant.h"
|
#include "blackmisc/variant.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@@ -29,6 +30,31 @@
|
|||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
|
class CPropertyIndex;
|
||||||
|
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
//! \private
|
||||||
|
template <class T, class X>
|
||||||
|
int compareByProperty(const T &a, const T &b, const CPropertyIndex &index, std::true_type, X)
|
||||||
|
{
|
||||||
|
return a.comparePropertyByIndex(index, b);
|
||||||
|
}
|
||||||
|
//! \private
|
||||||
|
template <class T>
|
||||||
|
int compareByProperty(const T &a, const T &b, const CPropertyIndex &index, std::false_type, std::true_type)
|
||||||
|
{
|
||||||
|
return compare(a.propertyByIndex(index), b.propertyByIndex(index));
|
||||||
|
}
|
||||||
|
//! \private
|
||||||
|
template <class T>
|
||||||
|
int compareByProperty(const T &, const T &, const CPropertyIndex &, std::false_type, std::false_type)
|
||||||
|
{
|
||||||
|
qFatal("Not implemented");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Property index. The index can be nested, that's why it is a sequence
|
* Property index. The index can be nested, that's why it is a sequence
|
||||||
* (e.g. PropertyIndexPilot, PropertyIndexRealname).
|
* (e.g. PropertyIndexPilot, PropertyIndexRealname).
|
||||||
@@ -175,6 +201,16 @@ namespace BlackMisc
|
|||||||
return static_cast<int>(ev) == l.first();
|
return static_cast<int>(ev) == l.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Return a predicate function which can compare two objects based on this index
|
||||||
|
auto comparator() const
|
||||||
|
{
|
||||||
|
return [index = *this](const auto &a, const auto &b)
|
||||||
|
{
|
||||||
|
using T = std::decay_t<decltype(a)>;
|
||||||
|
return Private::compareByProperty(a, b, index, HasCompareByPropertyIndex<T>(), HasPropertyByIndex<T>());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Mixin::String::toQString
|
//! \copydoc BlackMisc::Mixin::String::toQString
|
||||||
QString convertToQString(bool i18n = false) const;
|
QString convertToQString(bool i18n = false) const;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "iterator.h"
|
#include "iterator.h"
|
||||||
#include "containerbase.h"
|
#include "containerbase.h"
|
||||||
|
#include "propertyindex.h"
|
||||||
#include "icon.h"
|
#include "icon.h"
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -387,6 +388,21 @@ namespace BlackMisc
|
|||||||
sort(BlackMisc::Predicates::MemberLess(key1, keys...));
|
sort(BlackMisc::Predicates::MemberLess(key1, keys...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! In-place sort by some properties specified by a list of property indexes.
|
||||||
|
void sortByProperty(const CSequence<CPropertyIndex> &indexes)
|
||||||
|
{
|
||||||
|
sort([&indexes](const T &a, const T &b)
|
||||||
|
{
|
||||||
|
for (const auto &index : indexes)
|
||||||
|
{
|
||||||
|
int cmp = index.comparator()(a, b);
|
||||||
|
if (cmp < 0) { return true; }
|
||||||
|
if (cmp > 0) { return false; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//! Return a copy sorted by a given comparator predicate.
|
//! Return a copy sorted by a given comparator predicate.
|
||||||
template <class Predicate>
|
template <class Predicate>
|
||||||
CSequence sorted(Predicate p) const
|
CSequence sorted(Predicate p) const
|
||||||
@@ -405,6 +421,14 @@ namespace BlackMisc
|
|||||||
return sorted(BlackMisc::Predicates::MemberLess(key1, keys...));
|
return sorted(BlackMisc::Predicates::MemberLess(key1, keys...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Return a copy sorted by some properties specified by a list of property indexes.
|
||||||
|
CSequence sortedByProperty(const CSequence<CPropertyIndex> &indexes) const
|
||||||
|
{
|
||||||
|
CSequence result = *this;
|
||||||
|
result.sortByProperty(indexes);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//! In-place move the smallest n elements to the beginning and sort them.
|
//! In-place move the smallest n elements to the beginning and sort them.
|
||||||
template <class Predicate> void partiallySort(size_type n, Predicate p)
|
template <class Predicate> void partiallySort(size_type n, Predicate p)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class CPropertyIndex;
|
||||||
|
|
||||||
//! \cond PRIVATE
|
//! \cond PRIVATE
|
||||||
#ifdef BLACK_HAS_FIXED_CWG1558
|
#ifdef BLACK_HAS_FIXED_CWG1558
|
||||||
// Own implementation of C++17 std::void_t, simple variadic alias
|
// Own implementation of C++17 std::void_t, simple variadic alias
|
||||||
@@ -102,6 +104,28 @@ namespace BlackMisc
|
|||||||
struct HasCompare<T, U, void_t<decltype(compare(std::declval<T>(), std::declval<U>()))>> : public std::true_type {};
|
struct HasCompare<T, U, void_t<decltype(compare(std::declval<T>(), std::declval<U>()))>> : public std::true_type {};
|
||||||
//! \endcond
|
//! \endcond
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Trait which is true if the expression a.compareByPropertyIndex(b, i) is valid when a and b are instances of T,
|
||||||
|
* and i is an instance of CPropertyIndex.
|
||||||
|
*/
|
||||||
|
template <typename T, typename = void_t<>>
|
||||||
|
struct HasCompareByPropertyIndex : public std::false_type {};
|
||||||
|
//! \cond
|
||||||
|
template <typename T>
|
||||||
|
struct HasCompareByPropertyIndex<T, void_t<decltype(std::declval<T>().compareByPropertyIndex(std::declval<CPropertyIndex>(), std::declval<T>()))>> : public std::true_type {};
|
||||||
|
//! \endcond
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Trait which is true if the expression a.propertyByIndex(i) is valid with a is an instance of T and i is an
|
||||||
|
* instance of CPropertyIndex.
|
||||||
|
*/
|
||||||
|
template <typename T, typename = void_t<>>
|
||||||
|
struct HasPropertyByIndex : public std::false_type {};
|
||||||
|
//! \cond
|
||||||
|
template <typename T>
|
||||||
|
struct HasPropertyByIndex<T, void_t<decltype(std::declval<T>().propertyByIndex(std::declval<CPropertyIndex>()))>> : 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.
|
* Trait which is true if the expression a == b is valid when a and b are instances of T and U.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user