// Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include #include #include #include #include #include #include #include // 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 class tst_PointerAlgorithm : public QObject { Q_OBJECT private slots: void anyOf(); void count(); void contains(); void findOr(); void findOrDefault(); void toRawPointer(); void toReferences(); void take(); void takeOrDefault(); }; 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_PointerAlgorithm::anyOf() { { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); QVERIFY(Utils::anyOf(vector, ptrVector.at(0))); int foo = 42; QVERIFY(!Utils::anyOf(vector, &foo)); QVERIFY(Utils::anyOf(vector, nullptr)); } { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); std::vector ptrVector = Utils::toRawPointer(vector); QVERIFY(!Utils::anyOf(vector, nullptr)); } } void tst_PointerAlgorithm::count() { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::unique_ptr()); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); QCOMPARE(Utils::count(vector, ptrVector.at(0)), 1); int foo = 42; QCOMPARE(Utils::count(vector, &foo), 0); QCOMPARE(Utils::count(vector, nullptr), 2); } void tst_PointerAlgorithm::contains() { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); QVERIFY(Utils::contains(vector, ptrVector.at(0))); int foo = 42; QVERIFY(!Utils::contains(vector, &foo)); QVERIFY(Utils::contains(vector, nullptr)); } void tst_PointerAlgorithm::findOr() { { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(2)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); int foo = 42; int bar = 23; QVERIFY(Utils::findOr(vector, &foo, ptrVector.at(0)) == ptrVector.at(0)); QVERIFY(Utils::findOr(vector, nullptr, &foo) == nullptr); QVERIFY(Utils::findOr(vector, &foo, nullptr) == nullptr); QVERIFY(Utils::findOr(vector, &foo, &bar) == &foo); QCOMPARE(Utils::findOr(vector, &foo, [](const std::unique_ptr &ip) { return ip && *ip == 2; }), ptrVector.at(1)); QCOMPARE(Utils::findOr(vector, &foo, [](const std::unique_ptr &ip) { return ip && *ip == 43; }), &foo); } { std::vector> v3; v3.emplace_back(std::make_unique(1)); v3.emplace_back(std::make_unique(3)); v3.emplace_back(std::make_unique(5)); v3.emplace_back(std::make_unique(7)); Struct defS(6); QCOMPARE(Utils::findOr(v3, &defS, &Struct::isOdd), v3.at(0).get()); QCOMPARE(Utils::findOr(v3, &defS, &Struct::isEven), &defS); } { std::vector> v4; v4.emplace_back(std::make_shared(1)); v4.emplace_back(std::make_shared(3)); v4.emplace_back(std::make_shared(5)); v4.emplace_back(std::make_shared(7)); std::shared_ptr sharedDefS = std::make_shared(6); QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isOdd), v4.at(0)); QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isEven), sharedDefS); } } void tst_PointerAlgorithm::findOrDefault() { { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); int foo = 42; QVERIFY(Utils::findOrDefault(vector, ptrVector.at(0)) == ptrVector.at(0)); QVERIFY(Utils::findOrDefault(vector, &foo) == nullptr); } { std::vector> v2; v2.emplace_back(std::make_unique(1)); v2.emplace_back(std::make_unique(2)); v2.emplace_back(std::make_unique(3)); v2.emplace_back(std::make_unique(4)); QCOMPARE(Utils::findOrDefault(v2, [](const std::unique_ptr &ip) { return *ip == 2; }), v2.at(1).get()); QCOMPARE(Utils::findOrDefault(v2, [](const std::unique_ptr &ip) { return *ip == 5; }), static_cast(nullptr)); } { std::vector> v3; v3.emplace_back(std::make_unique(1)); v3.emplace_back(std::make_unique(3)); v3.emplace_back(std::make_unique(5)); v3.emplace_back(std::make_unique(7)); QCOMPARE(Utils::findOrDefault(v3, &Struct::isOdd), v3.at(0).get()); QCOMPARE(Utils::findOrDefault(v3, &Struct::isEven), static_cast(nullptr)); } } void tst_PointerAlgorithm::toRawPointer() { const std::vector> v; // same result container const std::vector x1 = Utils::toRawPointer(v); // different result container const std::vector x2 = Utils::toRawPointer(v); const QVector x3 = Utils::toRawPointer(v); const std::list x4 = Utils::toRawPointer(v); // different fully specified result container const std::vector x5 = Utils::toRawPointer>(v); const QVector x6 = Utils::toRawPointer>(v); } void tst_PointerAlgorithm::toReferences() { // toReference { // std::vector -> std::vector std::vector v; const std::vector> x = Utils::toReferences(v); } { // QList -> std::vector QList v; const std::vector> x = Utils::toReferences(v); } { // std::vector -> QList std::vector v; const QList> x = Utils::toReferences(v); } { // std::vector -> std::list std::vector v; const std::list> x = Utils::toReferences(v); } // toConstReference { // std::vector -> std::vector const std::vector v; const std::vector> x = Utils::toConstReferences(v); } { // QList -> std::vector const QList v; const std::vector> x = Utils::toConstReferences(v); } { // std::vector -> QList const std::vector v; const QList> x = Utils::toConstReferences(v); } { // std::vector -> std::list const std::vector v; const std::list> x = Utils::toConstReferences(v); } } void tst_PointerAlgorithm::take() { { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(2)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); int foo = 42; QVERIFY(Utils::take(vector, ptrVector.at(0)).value().get() == ptrVector.at(0)); QVERIFY(Utils::take(vector, ptrVector.at(0)) == std::nullopt); QVERIFY(Utils::take(vector, &foo) == std::nullopt); QVERIFY(Utils::take(vector, nullptr).value().get() == nullptr); } } void tst_PointerAlgorithm::takeOrDefault() { { std::vector> vector; vector.emplace_back(std::make_unique(5)); vector.emplace_back(std::make_unique(2)); vector.emplace_back(std::make_unique(6)); vector.emplace_back(std::make_unique(7)); vector.emplace_back(std::unique_ptr()); std::vector ptrVector = Utils::toRawPointer(vector); int foo = 42; QVERIFY(Utils::takeOrDefault(vector, ptrVector.at(0)).get() == ptrVector.at(0)); QVERIFY(Utils::takeOrDefault(vector, ptrVector.at(0)).get() == nullptr); QVERIFY(Utils::takeOrDefault(vector, &foo).get() == nullptr); QVERIFY(Utils::takeOrDefault(vector, nullptr).get() == nullptr); } } QTEST_GUILESS_MAIN(tst_PointerAlgorithm) #include "tst_pointeralgorithm.moc"