Files
qt-creator/tests/auto/algorithm/tst_algorithm.cpp
Marco Bubke a4a8fd5b81 Utils: Extend transform for container insertion
You can now return a container and it will be appended to the result
container. That has the drawback of generating temporary container but
if we get them already it makes the code much more readable than a raw
loop.

Change-Id: Ibcd38e85ef759c18cd8da0fac0185f0f6fc123e2
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
2023-10-04 11:47:26 +00:00

675 lines
25 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest>
#include <array>
#include <deque>
#include <list>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
// must get included after the containers above or gcc4.9 will have a problem using
// initializer_list related code on the templates inside algorithm.h
#include <utils/algorithm.h>
class tst_Algorithm : public QObject
{
Q_OBJECT
private slots:
void anyOf();
void transform();
void sort();
void contains();
void findOr();
void findOrDefault();
void toReferences();
void take();
void sorted();
};
int stringToInt(const QString &s)
{
return s.toInt();
}
namespace {
struct BaseStruct
{
BaseStruct(int m) : member(m) {}
bool operator==(const BaseStruct &other) const { return member == other.member; }
int member;
};
struct Struct : public BaseStruct
{
Struct(int m) : BaseStruct(m) {}
bool isOdd() const { return member % 2 == 1; }
bool isEven() const { return !isOdd(); }
int getMember() const { return member; }
};
}
void tst_Algorithm::anyOf()
{
{
const QList<QString> strings({"1", "3", "132"});
QVERIFY(Utils::anyOf(strings, [](const QString &s) { return s == "132"; }));
QVERIFY(!Utils::anyOf(strings, [](const QString &s) { return s == "1324"; }));
}
{
const QList<Struct> list({2, 4, 6, 8});
QVERIFY(Utils::anyOf(list, &Struct::isEven));
QVERIFY(!Utils::anyOf(list, &Struct::isOdd));
}
{
const QList<Struct> list({0, 0, 0, 0, 1, 0, 0});
QVERIFY(Utils::anyOf(list, &Struct::member));
}
{
const QList<Struct> list({0, 0, 0, 0, 0, 0, 0});
QVERIFY(!Utils::anyOf(list, &Struct::member));
}
}
void tst_Algorithm::transform()
{
// same container type
{
// QList has standard inserter
const QList<QString> strings({"1", "3", "132"});
const QList<int> i1 = Utils::transform(strings, [](const QString &s) { return s.toInt(); });
QCOMPARE(i1, QList<int>({1, 3, 132}));
const QList<int> i2 = Utils::transform(strings, stringToInt);
QCOMPARE(i2, QList<int>({1, 3, 132}));
const QList<qsizetype> i3 = Utils::transform(strings, &QString::size);
QCOMPARE(i3, QList<qsizetype>({1, 1, 3}));
}
{
// QStringList
const QStringList strings({"1", "3", "132"});
const QList<int> i1 = Utils::transform(strings, [](const QString &s) { return s.toInt(); });
QCOMPARE(i1, QList<int>({1, 3, 132}));
const QList<int> i2 = Utils::transform(strings, stringToInt);
QCOMPARE(i2, QList<int>({1, 3, 132}));
const QList<qsizetype> i3 = Utils::transform(strings, &QString::size);
QCOMPARE(i3, QList<qsizetype>({1, 1, 3}));
}
{
// QSet internally needs special inserter
const QSet<QString> strings({QString("1"), QString("3"), QString("132")});
const QSet<int> i1 = Utils::transform(strings, [](const QString &s) { return s.toInt(); });
QCOMPARE(i1, QSet<int>({1, 3, 132}));
const QSet<int> i2 = Utils::transform(strings, stringToInt);
QCOMPARE(i2, QSet<int>({1, 3, 132}));
const QSet<qsizetype> i3 = Utils::transform(strings, &QString::size);
QCOMPARE(i3, QSet<qsizetype>({1, 3}));
}
// different container types
{
// QList to QSet
const QList<QString> strings({"1", "3", "132"});
const QSet<int> i1 = Utils::transform<QSet>(strings, [](const QString &s) { return s.toInt(); });
QCOMPARE(i1, QSet<int>({1, 3, 132}));
const QSet<int> i2 = Utils::transform<QSet>(strings, stringToInt);
QCOMPARE(i2, QSet<int>({1, 3, 132}));
const QSet<qsizetype> i3 = Utils::transform<QSet>(strings, &QString::size);
QCOMPARE(i3, QSet<qsizetype>({1, 3}));
}
{
// QStringList to QSet
const QStringList strings({"1", "3", "132"});
const QSet<int> i1 = Utils::transform<QSet>(strings, [](const QString &s) { return s.toInt(); });
QCOMPARE(i1, QSet<int>({1, 3, 132}));
const QSet<int> i2 = Utils::transform<QSet>(strings, stringToInt);
QCOMPARE(i2, QSet<int>({1, 3, 132}));
const QSet<qsizetype> i3 = Utils::transform<QSet>(strings, &QString::size);
QCOMPARE(i3, QSet<qsizetype>({1, 3}));
}
{
// QSet to QList
const QSet<QString> strings({QString("1"), QString("3"), QString("132")});
QList<int> i1 = Utils::transform<QList>(strings, [](const QString &s) { return s.toInt(); });
Utils::sort(i1);
QCOMPARE(i1, QList<int>({1, 3, 132}));
QList<int> i2 = Utils::transform<QList>(strings, stringToInt);
Utils::sort(i2);
QCOMPARE(i2, QList<int>({1, 3, 132}));
QList<qsizetype> i3 = Utils::transform<QList>(strings, &QString::size);
QCOMPARE(Utils::sorted(i3), QList<qsizetype>({1, 1, 3}));
}
{
const QList<Struct> list({4, 3, 2, 1, 2});
const QList<int> trans = Utils::transform(list, &Struct::member);
QCOMPARE(trans, QList<int>({4, 3, 2, 1, 2}));
}
{
// QList -> std::vector
const QList<int> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform<std::vector>(v, [](int i) { return i + 1; });
QCOMPARE(trans, std::vector<int>({2, 3, 4, 5}));
}
{
// QList -> std::vector
const QList<Struct> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform<std::vector>(v, &Struct::getMember);
QCOMPARE(trans, std::vector<int>({1, 2, 3, 4}));
}
{
// QList -> std::vector
const QList<Struct> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform<std::vector>(v, &Struct::member);
QCOMPARE(trans, std::vector<int>({1, 2, 3, 4}));
}
{
// std::vector -> QList
const std::vector<int> v({1, 2, 3, 4});
const QList<int> trans = Utils::transform<QList>(v, [](int i) { return i + 1; });
QCOMPARE(trans, QList<int>({2, 3, 4, 5}));
}
{
// std::vector -> QList
const std::vector<Struct> v({1, 2, 3, 4});
const QList<int> trans = Utils::transform<QList>(v, &Struct::getMember);
QCOMPARE(trans, QList<int>({1, 2, 3, 4}));
}
{
// std::vector -> QList
const std::vector<Struct> v({1, 2, 3, 4});
const QList<int> trans = Utils::transform<QList>(v, &Struct::member);
QCOMPARE(trans, QList<int>({1, 2, 3, 4}));
}
{
// std::deque -> std::vector
const std::deque<int> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform<std::vector>(v, [](int i) { return i + 1; });
QCOMPARE(trans, std::vector<int>({2, 3, 4, 5}));
}
{
// std::deque -> std::vector
const std::deque<Struct> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform<std::vector>(v, &Struct::getMember);
QCOMPARE(trans, std::vector<int>({1, 2, 3, 4}));
}
{
// std::deque -> std::vector
const std::deque<Struct> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform<std::vector>(v, &Struct::member);
QCOMPARE(trans, std::vector<int>({1, 2, 3, 4}));
}
{
// std::vector -> std::vector
const std::vector<int> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform(v, [](int i) { return i + 1; });
QCOMPARE(trans, std::vector<int>({2, 3, 4, 5}));
}
{
// std::vector -> std::vector
const std::vector<Struct> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform(v, &Struct::getMember);
QCOMPARE(trans, std::vector<int>({1, 2, 3, 4}));
}
{
// std::vector -> std::vector
const std::vector<Struct> v({1, 2, 3, 4});
const std::vector<int> trans = Utils::transform(v, &Struct::member);
QCOMPARE(trans, std::vector<int>({1, 2, 3, 4}));
}
{
// std::unordered_map -> QList
std::unordered_map<int, double> m;
m.emplace(1, 1.5);
m.emplace(3, 2.5);
m.emplace(5, 3.5);
QList<double> trans = Utils::transform<QList>(m, [](const std::pair<int, double> &in) {
return in.first * in.second;
});
Utils::sort(trans);
QCOMPARE(trans, QList<double>({1.5, 7.5, 17.5}));
}
{
// specific result container with one template parameter (QVector)
std::vector<int> v({1, 2, 3, 4});
const QVector<BaseStruct *> trans = Utils::transform<QVector<BaseStruct *>>(v, [](int i) {
return new Struct(i);
});
QCOMPARE(trans.size(), 4);
QCOMPARE(trans.at(0)->member, 1);
QCOMPARE(trans.at(1)->member, 2);
QCOMPARE(trans.at(2)->member, 3);
QCOMPARE(trans.at(3)->member, 4);
qDeleteAll(trans);
}
{
// specific result container with one of two template parameters (std::vector)
std::vector<int> v({1, 2, 3, 4});
const std::vector<BaseStruct *> trans
= Utils::transform<std::vector<BaseStruct *>>(v, [](int i) { return new Struct(i); });
QCOMPARE(trans.size(), static_cast<std::vector<int>::size_type>(4ul));
QCOMPARE(trans.at(0)->member, 1);
QCOMPARE(trans.at(1)->member, 2);
QCOMPARE(trans.at(2)->member, 3);
QCOMPARE(trans.at(3)->member, 4);
qDeleteAll(trans);
}
{
// specific result container with two template parameters (std::vector)
std::vector<int> v({1, 2, 3, 4});
const std::vector<BaseStruct *, std::allocator<BaseStruct *>> trans
= Utils::transform<std::vector<BaseStruct *, std::allocator<BaseStruct *>>>(v, [](int i) {
return new Struct(i);
});
QCOMPARE(trans.size(), static_cast<std::vector<int>::size_type>(4ul));
QCOMPARE(trans.at(0)->member, 1);
QCOMPARE(trans.at(1)->member, 2);
QCOMPARE(trans.at(2)->member, 3);
QCOMPARE(trans.at(3)->member, 4);
qDeleteAll(trans);
}
{
// specific result container with member function
QList<Struct> v({1, 2, 3, 4});
const QVector<double> trans = Utils::transform<QVector<double>>(v, &Struct::getMember);
QCOMPARE(trans, QVector<double>({1.0, 2.0, 3.0, 4.0}));
}
{
// specific result container with member
QList<Struct> v({1, 2, 3, 4});
const QVector<double> trans = Utils::transform<QVector<double>>(v, &Struct::member);
QCOMPARE(trans, QVector<double>({1.0, 2.0, 3.0, 4.0}));
}
{
// non-const container and function parameter
// same container type
std::vector<Struct> v({1, 2, 3, 4});
const std::vector<std::reference_wrapper<Struct>> trans
= Utils::transform(v, [](Struct &s) { return std::ref(s); });
// different container type
QVector<Struct> v2({1, 2, 3, 4});
const std::vector<std::reference_wrapper<Struct>> trans2
= Utils::transform<std::vector>(v, [](Struct &s) { return std::ref(s); });
// temporaries
const auto tempv = [] { return QList<Struct>({1, 2, 3, 4}); };
// temporary with member function
const QList<int> trans3 = Utils::transform(tempv(), &Struct::getMember);
const std::vector<int> trans4 = Utils::transform<std::vector>(tempv(), &Struct::getMember);
const std::vector<int> trans5 = Utils::transform<std::vector<int>>(tempv(), &Struct::getMember);
// temporary with member
const QList<int> trans6 = Utils::transform(tempv(), &Struct::member);
const std::vector<int> trans7 = Utils::transform<std::vector>(tempv(), &Struct::member);
const std::vector<int> trans8 = Utils::transform<std::vector<int>>(tempv(), &Struct::member);
// temporary with function
const QList<int> trans9 = Utils::transform(tempv(),
[](const Struct &s) { return s.getMember(); });
const std::vector<int> trans10 = Utils::transform<std::vector>(tempv(), [](const Struct &s) {
return s.getMember();
});
const std::vector<int> trans11 = Utils::transform<std::vector<int>>(tempv(),
[](const Struct &s) {
return s.getMember();
});
}
// target containers without reserve(...)
{
// std::vector -> std::deque
const std::vector<int> v({1, 2, 3, 4});
const std::deque<int> trans = Utils::transform<std::deque>(v, [](int i) { return i + 1; });
QCOMPARE(trans, std::deque<int>({2, 3, 4, 5}));
}
{
// std::vector -> std::list
const std::vector<int> v({1, 2, 3, 4});
const std::list<int> trans = Utils::transform<std::list>(v, [](int i) { return i + 1; });
QCOMPARE(trans, std::list<int>({2, 3, 4, 5}));
}
{
// std::vector -> std::set
const std::vector<int> v({1, 2, 3, 4});
const std::set<int> trans = Utils::transform<std::set<int>>(v, [](int i) { return i + 1; });
QCOMPARE(trans, std::set<int>({2, 3, 4, 5}));
}
// various map/set/hash without push_back
{
// std::vector -> std::map
const std::vector<int> v({1, 2, 3, 4});
const std::map<int, int> trans = Utils::transform<std::map<int, int>>(v, [](int i) {
return std::make_pair(i, i + 1);
});
const std::map<int, int> expected({{1, 2}, {2, 3}, {3, 4}, {4, 5}});
QCOMPARE(trans, expected);
}
{
// std::vector -> std::unordered_set
const std::vector<int> v({1, 2, 3, 4});
const std::unordered_set<int> trans = Utils::transform<std::unordered_set<int>>(v, [](int i) {
return i + 1;
});
QCOMPARE(trans, std::unordered_set<int>({2, 3, 4, 5}));
}
{
// std::vector -> std::unordered_map
const std::vector<int> v({1, 2, 3, 4});
const std::unordered_map<int, int> trans
= Utils::transform<std::unordered_map<int, int>>(v, [](int i) {
return std::make_pair(i, i + 1);
});
const std::unordered_map<int, int> expected({{1, 2}, {2, 3}, {3, 4}, {4, 5}});
QCOMPARE(trans, expected);
}
{
// std::vector -> QMap using std::pair
const std::vector<int> v({1, 2, 3, 4});
const QMap<int, int> trans = Utils::transform<QMap<int, int>>(v, [](int i) {
return std::make_pair(i, i + 1);
});
const QMap<int, int> expected({{1, 2}, {2, 3}, {3, 4}, {4, 5}});
QCOMPARE(trans, expected);
}
{
// std::vector -> QMap using QPair
const std::vector<int> v({1, 2, 3, 4});
const QMap<int, int> trans = Utils::transform<QMap<int, int>>(v, [](int i) {
return qMakePair(i, i + 1);
});
const QMap<int, int> expected({{1, 2}, {2, 3}, {3, 4}, {4, 5}});
QCOMPARE(trans, expected);
}
{
// std::vector -> QHash using std::pair
const std::vector<int> v({1, 2, 3, 4});
const QHash<int, int> trans = Utils::transform<QHash<int, int>>(v, [](int i) {
return std::make_pair(i, i + 1);
});
const QHash<int, int> expected({{1, 2}, {2, 3}, {3, 4}, {4, 5}});
QCOMPARE(trans, expected);
}
{
// std::vector -> QHash using QPair
const std::vector<int> v({1, 2, 3, 4});
const QHash<int, int> trans = Utils::transform<QHash<int, int>>(v, [](int i) {
return qMakePair(i, i + 1);
});
const QHash<int, int> expected({{1, 2}, {2, 3}, {3, 4}, {4, 5}});
QCOMPARE(trans, expected);
}
{
// std::vector -> std::vector appending container
const std::vector<int> v({1, 2, 3, 4});
const auto trans = Utils::transform<std::vector<int>>(v, [](int i) -> std::vector<int> {
return {i, i * 2};
});
const std::vector<int> expected{1, 2, 2, 4, 3, 6, 4, 8};
QCOMPARE(trans, expected);
}
{
// QList -> QList appending container
const QList<int> v({1, 2, 3, 4});
const auto trans = Utils::transform<QList<int>>(v, [](int i) -> QList<int> {
return {i, i * 2};
});
const QList<int> expected{1, 2, 2, 4, 3, 6, 4, 8};
QCOMPARE(trans, expected);
}
}
void tst_Algorithm::sort()
{
QStringList s1({"3", "2", "1"});
Utils::sort(s1);
QCOMPARE(s1, QStringList({"1", "2", "3"}));
QStringList s2({"13", "31", "22"});
Utils::sort(s2, [](const QString &a, const QString &b) { return a[1] < b[1]; });
QCOMPARE(s2, QStringList({"31", "22", "13"}));
QList<QString> s3({"12345", "3333", "22"});
Utils::sort(s3, &QString::size);
QCOMPARE(s3, QList<QString>({"22", "3333", "12345"}));
QList<Struct> s4({4, 3, 2, 1});
Utils::sort(s4, &Struct::member);
QCOMPARE(s4, QList<Struct>({1, 2, 3, 4}));
// member function with pointers
QList<QString> arr1({"12345", "3333", "22"});
QList<QString *> s5({&arr1[0], &arr1[1], &arr1[2]});
QCOMPARE(Utils::sorted(s5, &QString::size), QList<QString *>({&arr1[2], &arr1[1], &arr1[0]}));
// member with pointers
QList<Struct> arr2({4, 1, 3});
QList<Struct *> s6({&arr2[0], &arr2[1], &arr2[2]});
QCOMPARE(Utils::sorted(s6, &Struct::member), QList<Struct *>({&arr2[1], &arr2[2], &arr2[0]}));
// std::array:
std::array<int, 4> array = {{4, 10, 8, 1}};
Utils::sort(array);
std::array<int, 4> arrayResult = {{1, 4, 8, 10}};
QCOMPARE(array, arrayResult);
// valarray (no begin/end member functions):
std::valarray<int> valarray(array.data(), array.size());
std::valarray<int> valarrayResult(arrayResult.data(), arrayResult.size());
Utils::sort(valarray);
QCOMPARE(valarray.size(), valarrayResult.size());
for (size_t i = 0; i < valarray.size(); ++i)
QCOMPARE(valarray[i], valarrayResult[i]);
}
void tst_Algorithm::contains()
{
std::vector<int> v1{1, 2, 3, 4};
QVERIFY(Utils::contains(v1, [](int i) { return i == 2; }));
QVERIFY(!Utils::contains(v1, [](int i) { return i == 5; }));
std::vector<Struct> structs = {2, 4, 6, 8};
QVERIFY(Utils::contains(structs, &Struct::isEven));
QVERIFY(!Utils::contains(structs, &Struct::isOdd));
QList<Struct> structQlist = {2, 4, 6, 8};
QVERIFY(Utils::contains(structQlist, &Struct::isEven));
QVERIFY(!Utils::contains(structQlist, &Struct::isOdd));
}
void tst_Algorithm::findOr()
{
std::vector<int> v1{1, 2, 3, 4};
QCOMPARE(Utils::findOr(v1, 10, [](int i) { return i == 2; }), 2);
QCOMPARE(Utils::findOr(v1, 10, [](int i) { return i == 5; }), 10);
}
void tst_Algorithm::findOrDefault()
{
{
std::vector<int> v1{1, 2, 3, 4};
QCOMPARE(Utils::findOrDefault(v1, [](int i) { return i == 2; }), 2);
QCOMPARE(Utils::findOrDefault(v1, [](int i) { return i == 5; }), 0);
}
{
std::vector<std::shared_ptr<Struct>> v4;
v4.emplace_back(std::make_shared<Struct>(1));
v4.emplace_back(std::make_shared<Struct>(3));
v4.emplace_back(std::make_shared<Struct>(5));
v4.emplace_back(std::make_shared<Struct>(7));
QCOMPARE(Utils::findOrDefault(v4, &Struct::isOdd), v4.at(0));
QCOMPARE(Utils::findOrDefault(v4, &Struct::isEven), std::shared_ptr<Struct>());
}
}
void tst_Algorithm::toReferences()
{
// toReference
{
// std::vector -> std::vector
std::vector<Struct> v;
const std::vector<std::reference_wrapper<Struct>> x = Utils::toReferences(v);
}
{
// QList -> std::vector
QList<Struct> v;
const std::vector<std::reference_wrapper<Struct>> x = Utils::toReferences<std::vector>(v);
}
{
// std::vector -> QList
std::vector<Struct> v;
const QList<std::reference_wrapper<Struct>> x = Utils::toReferences<QList>(v);
}
{
// std::vector -> std::list
std::vector<Struct> v;
const std::list<std::reference_wrapper<Struct>> x = Utils::toReferences<std::list>(v);
}
// toConstReference
{
// std::vector -> std::vector
const std::vector<Struct> v;
const std::vector<std::reference_wrapper<const Struct>> x = Utils::toConstReferences(v);
}
{
// QList -> std::vector
const QList<Struct> v;
const std::vector<std::reference_wrapper<const Struct>> x
= Utils::toConstReferences<std::vector>(v);
}
{
// std::vector -> QList
const std::vector<Struct> v;
const QList<std::reference_wrapper<const Struct>> x = Utils::toConstReferences<QList>(v);
}
{
// std::vector -> std::list
const std::vector<Struct> v;
const std::list<std::reference_wrapper<const Struct>> x
= Utils::toConstReferences<std::list>(v);
}
}
void tst_Algorithm::take()
{
{
QList<Struct> v {1, 3, 5, 6, 7, 8, 9, 11, 13, 15, 13, 16, 17};
std::optional<Struct> r1 = Utils::take(v, [](const Struct &s) { return s.member == 13; });
QVERIFY(static_cast<bool>(r1));
QCOMPARE(r1.value().member, 13);
std::optional<Struct> r2 = Utils::take(v, [](const Struct &s) { return s.member == 13; });
QVERIFY(static_cast<bool>(r2));
QCOMPARE(r2.value().member, 13);
std::optional<Struct> r3 = Utils::take(v, [](const Struct &s) { return s.member == 13; });
QVERIFY(!static_cast<bool>(r3));
std::optional<Struct> r4 = Utils::take(v, &Struct::isEven);
QVERIFY(static_cast<bool>(r4));
QCOMPARE(r4.value().member, 6);
}
{
QList<Struct> v {0, 0, 0, 0, 0, 0, 1, 2, 3};
std::optional<Struct> r1 = Utils::take(v, &Struct::member);
QVERIFY(static_cast<bool>(r1));
QCOMPARE(r1.value().member, 1);
}
}
void tst_Algorithm::sorted()
{
const QList<int> vOrig{4, 3, 6, 5, 8};
const QList<int> vExpected{3, 4, 5, 6, 8};
// plain
{
// non-const lvalue
QList<int> vncl = vOrig;
const QList<int> rncl = Utils::sorted(vncl);
QCOMPARE(rncl, vExpected);
QCOMPARE(vncl, vOrig); // was not modified
// const lvalue
const QList<int> rcl = Utils::sorted(vOrig);
QCOMPARE(rcl, vExpected);
// non-const rvalue
const auto vncr = [vOrig]() -> QList<int> { return vOrig; };
const QList<int> rncr = Utils::sorted(vncr());
QCOMPARE(rncr, vExpected);
// const rvalue
const auto vcr = [vOrig]() -> const QList<int> { return vOrig; };
const QList<int> rcr = Utils::sorted(vcr());
QCOMPARE(rcr, vExpected);
}
// predicate
{
// non-const lvalue
QList<int> vncl = vOrig;
const QList<int> rncl = Utils::sorted(vncl, [](int a, int b) { return a < b; });
QCOMPARE(rncl, vExpected);
QCOMPARE(vncl, vOrig); // was not modified
// const lvalue
const QList<int> rcl = Utils::sorted(vOrig, [](int a, int b) { return a < b; });
QCOMPARE(rcl, vExpected);
// non-const rvalue
const auto vncr = [vOrig]() -> QList<int> { return vOrig; };
const QList<int> rncr = Utils::sorted(vncr(), [](int a, int b) { return a < b; });
QCOMPARE(rncr, vExpected);
// const rvalue
const auto vcr = [vOrig]() -> const QList<int> { return vOrig; };
const QList<int> rcr = Utils::sorted(vcr(), [](int a, int b) { return a < b; });
QCOMPARE(rcr, vExpected);
}
const QList<Struct> mvOrig({4, 3, 2, 1});
const QList<Struct> mvExpected({1, 2, 3, 4});
// member
{
// non-const lvalue
QList<Struct> mvncl = mvOrig;
const QList<Struct> rncl = Utils::sorted(mvncl, &Struct::member);
QCOMPARE(rncl, mvExpected);
QCOMPARE(mvncl, mvOrig); // was not modified
// const lvalue
const QList<Struct> rcl = Utils::sorted(mvOrig, &Struct::member);
QCOMPARE(rcl, mvExpected);
// non-const rvalue
const auto vncr = [mvOrig]() -> QList<Struct> { return mvOrig; };
const QList<Struct> rncr = Utils::sorted(vncr(), &Struct::member);
QCOMPARE(rncr, mvExpected);
// const rvalue
const auto vcr = [mvOrig]() -> const QList<Struct> { return mvOrig; };
const QList<Struct> rcr = Utils::sorted(vcr(), &Struct::member);
QCOMPARE(rcr, mvExpected);
}
// member function
{
// non-const lvalue
QList<Struct> mvncl = mvOrig;
const QList<Struct> rncl = Utils::sorted(mvncl, &Struct::getMember);
QCOMPARE(rncl, mvExpected);
QCOMPARE(mvncl, mvOrig); // was not modified
// const lvalue
const QList<Struct> rcl = Utils::sorted(mvOrig, &Struct::getMember);
QCOMPARE(rcl, mvExpected);
// non-const rvalue
const auto vncr = [mvOrig]() -> QList<Struct> { return mvOrig; };
const QList<Struct> rncr = Utils::sorted(vncr(), &Struct::getMember);
QCOMPARE(rncr, mvExpected);
// const rvalue
const auto vcr = [mvOrig]() -> const QList<Struct> { return mvOrig; };
const QList<Struct> rcr = Utils::sorted(vcr(), &Struct::getMember);
QCOMPARE(rcr, mvExpected);
}
}
QTEST_GUILESS_MAIN(tst_Algorithm)
#include "tst_algorithm.moc"