mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-23 05:45:35 +08:00
Fixed buggy CSequence::sortBy when sorting by multiple members.
Implementation of Predicates::MemberLess was wrong, so replaced it with a simpler one. Also added a regression test and removed unused code.
This commit is contained in:
committed by
Klaus Basan
parent
f2bd767c63
commit
8a058202ed
@@ -144,17 +144,6 @@ namespace BlackMisc
|
|||||||
|
|
||||||
namespace Private
|
namespace Private
|
||||||
{
|
{
|
||||||
//! \private
|
|
||||||
template <typename T, typename F, size_t... Is>
|
|
||||||
void tupleForEachImpl(T &&tuple, F &&visitor, std::index_sequence<Is...>)
|
|
||||||
{
|
|
||||||
// parameter pack swallow idiom
|
|
||||||
static_cast<void>(std::initializer_list<int>
|
|
||||||
{
|
|
||||||
//! \fixme C-style cast is needed due to a clang bug: https://bugs.llvm.org/show_bug.cgi?id=39375
|
|
||||||
((void)(std::forward<F>(visitor)(std::get<Is>(std::forward<T>(tuple)))), 0)...
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//! \private
|
//! \private
|
||||||
template <typename T, typename F, size_t... Is>
|
template <typename T, typename F, size_t... Is>
|
||||||
void tupleForEachPairImpl(T &&tuple, F &&visitor, std::index_sequence<Is...>)
|
void tupleForEachPairImpl(T &&tuple, F &&visitor, std::index_sequence<Is...>)
|
||||||
@@ -168,16 +157,6 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* Invoke a visitor function on each element of a tuple in order.
|
|
||||||
*/
|
|
||||||
template <typename T, typename F>
|
|
||||||
void tupleForEach(T &&tuple, F &&visitor)
|
|
||||||
{
|
|
||||||
using seq = std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>;
|
|
||||||
return Private::tupleForEachImpl(std::forward<T>(tuple), std::forward<F>(visitor), seq());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Invoke a visitor function on each pair of elements of a tuple in order.
|
* Invoke a visitor function on each pair of elements of a tuple in order.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -62,15 +62,7 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
return [vs...](const auto &a, const auto &b)
|
return [vs...](const auto &a, const auto &b)
|
||||||
{
|
{
|
||||||
bool less = true;
|
return std::forward_as_tuple((a.*vs)()...) < std::forward_as_tuple((b.*vs)()...);
|
||||||
bool greater = false;
|
|
||||||
tupleForEach(std::make_tuple(vs...), [ & ](auto member)
|
|
||||||
{
|
|
||||||
less = less && ! greater && (a.*member)() < (b.*member)();
|
|
||||||
greater = (b.*member)() < (a.*member)();
|
|
||||||
});
|
|
||||||
Q_UNUSED(greater); // CPP style check
|
|
||||||
return less;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,9 +111,7 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
return [vs...](const auto &a, const auto &b)
|
return [vs...](const auto &a, const auto &b)
|
||||||
{
|
{
|
||||||
bool equal = true;
|
return std::forward_as_tuple((a.*vs)()...) == std::forward_as_tuple((b.*vs)()...);
|
||||||
tupleForEach(std::make_tuple(vs...), [ & ](auto member) { equal = equal && (a.*member)() == (b.*member)(); });
|
|
||||||
return equal;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ namespace BlackMiscTest
|
|||||||
void sequenceBasics();
|
void sequenceBasics();
|
||||||
void joinAndSplit();
|
void joinAndSplit();
|
||||||
void findTests();
|
void findTests();
|
||||||
|
void sortTests();
|
||||||
void dictionaryBasics();
|
void dictionaryBasics();
|
||||||
void timestampList();
|
void timestampList();
|
||||||
void offsetTimestampList();
|
void offsetTimestampList();
|
||||||
@@ -169,6 +170,35 @@ namespace BlackMiscTest
|
|||||||
QVERIFY2(found.size() == 1, "found");
|
QVERIFY2(found.size() == 1, "found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTestContainers::sortTests()
|
||||||
|
{
|
||||||
|
struct Person
|
||||||
|
{
|
||||||
|
const QString &getName() const { return name; }
|
||||||
|
int getAge() const { return age; }
|
||||||
|
bool operator==(const Person &other) const { return name == other.name && age == other.age; }
|
||||||
|
QString name;
|
||||||
|
int age;
|
||||||
|
};
|
||||||
|
CSequence<Person> list
|
||||||
|
{
|
||||||
|
{ "Alice", 33 },
|
||||||
|
{ "Bob", 32 },
|
||||||
|
{ "Cathy", 32 },
|
||||||
|
{ "Dave", 31 },
|
||||||
|
{ "Emily", 31 }
|
||||||
|
};
|
||||||
|
CSequence<Person> sorted
|
||||||
|
{
|
||||||
|
{ "Dave", 31 },
|
||||||
|
{ "Emily", 31 },
|
||||||
|
{ "Bob", 32 },
|
||||||
|
{ "Cathy", 32 },
|
||||||
|
{ "Alice", 33 }
|
||||||
|
};
|
||||||
|
QVERIFY2(list.sortedBy(&Person::getAge, &Person::getName) == sorted, "sort by multiple members");
|
||||||
|
}
|
||||||
|
|
||||||
void CTestContainers::dictionaryBasics()
|
void CTestContainers::dictionaryBasics()
|
||||||
{
|
{
|
||||||
CTestValueObject key1("Key1", "This is key object 1");
|
CTestValueObject key1("Key1", "This is key object 1");
|
||||||
|
|||||||
Reference in New Issue
Block a user