From 566b118a873652bf9a5f7d72efcc379698ca9675 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 27 Nov 2017 11:31:15 +0100 Subject: [PATCH] Utils: Make algorithms take more containers Change-Id: I05bd1052bbc2c6481fdec8a3763d9ae4f3dc8f44 Reviewed-by: hjk Reviewed-by: Eike Ziller --- src/libs/utils/algorithm.h | 57 ++++++++++++++------------ tests/auto/algorithm/tst_algorithm.cpp | 14 +++++++ 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 3d0b9a6acb4..2f337730005 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -45,19 +45,19 @@ namespace Utils template bool anyOf(const T &container, R (S::*predicate)() const) { - return std::any_of(container.begin(), container.end(), std::mem_fn(predicate)); + return std::any_of(std::begin(container), std::end(container), std::mem_fn(predicate)); } template bool anyOf(const T &container, F predicate) { - return std::any_of(container.begin(), container.end(), predicate); + return std::any_of(std::begin(container), std::end(container), predicate); } template int count(const T &container, F predicate) { - return std::count_if(container.begin(), container.end(), predicate); + return std::count_if(std::begin(container), std::end(container), predicate); } ////////////////// @@ -66,27 +66,28 @@ int count(const T &container, F predicate) template bool allOf(const T &container, F predicate) { - return std::all_of(container.begin(), container.end(), predicate); + return std::all_of(std::begin(container), std::end(container), predicate); } ////////////////// // erase ///////////////// template -void erase(QList &container, F predicate) +void erase(T &container, F predicate) { - container.erase(std::remove_if(container.begin(), container.end(), predicate), - container.end()); + container.erase(std::remove_if(std::begin(container), std::end(container), predicate), + std::end(container)); } + ////////////////// // contains ///////////////// template bool contains(const T &container, F function) { - typename T::const_iterator end = container.end(); - typename T::const_iterator begin = container.begin(); + typename T::const_iterator begin = std::begin(container); + typename T::const_iterator end = std::end(container); typename T::const_iterator it = std::find_if(begin, end, function); return it != end; @@ -98,8 +99,8 @@ bool contains(const T &container, F function) template typename T::value_type findOr(const T &container, typename T::value_type other, F function) { - typename T::const_iterator end = container.end(); - typename T::const_iterator begin = container.begin(); + typename T::const_iterator begin = std::begin(container); + typename T::const_iterator end = std::end(container); typename T::const_iterator it = std::find_if(begin, end, function); if (it == end) @@ -117,8 +118,8 @@ typename T::value_type findOr(const T &container, typename T::value_type other, template int indexOf(const T &container, F function) { - typename T::const_iterator end = container.end(); - typename T::const_iterator begin = container.begin(); + typename T::const_iterator begin = std::begin(container); + typename T::const_iterator end = std::end(container); typename T::const_iterator it = std::find_if(begin, end, function); if (it == end) @@ -145,8 +146,8 @@ typename T::value_type findOrDefault(const T &container, R (S::*function)() cons template typename T::value_type maxElementOr(const T &container, typename T::value_type other) { - typename T::const_iterator end = container.end(); - typename T::const_iterator begin = container.begin(); + typename T::const_iterator begin = std::begin(container); + typename T::const_iterator end = std::end(container); typename T::const_iterator it = std::max_element(begin, end); if (it == end) @@ -299,7 +300,7 @@ Q_REQUIRED_RESULT C filtered(const C &container, F predicate) { C out; - std::copy_if(container.begin(), container.end(), + std::copy_if(std::begin(container), std::end(container), inserter(out), predicate); return out; } @@ -309,7 +310,7 @@ Q_REQUIRED_RESULT C filtered(const C &container, R (S::*predicate)() const) { C out; - std::copy_if(container.begin(), container.end(), + std::copy_if(std::begin(container), std::end(container), inserter(out), std::mem_fn(predicate)); return out; } @@ -361,8 +362,8 @@ C filteredUnique(const C &container) QSet seen; int setSize = 0; - auto endIt = container.end(); - for (auto it = container.begin(); it != endIt; ++it) { + auto endIt = std::end(container); + for (auto it = std::begin(container); it != endIt; ++it) { seen.insert(*it); if (setSize == seen.size()) // unchanged size => was already seen continue; @@ -391,35 +392,37 @@ Container qobject_container_cast(const Container &container) // sort ///////////////// template -inline void sort(Container &c) +inline void sort(Container &container) { - std::sort(c.begin(), c.end()); + std::sort(std::begin(container), std::end(container)); } template -inline void sort(Container &c, Predicate p) +inline void sort(Container &container, Predicate p) { - std::sort(c.begin(), c.end(), p); + std::sort(std::begin(container), std::end(container), p); } // pointer to member template -inline void sort(Container &c, R S::*member) +inline void sort(Container &container, R S::*member) { auto f = std::mem_fn(member); using const_ref = typename Container::const_reference; - std::sort(c.begin(), c.end(), [&f](const_ref a, const_ref b) { + std::sort(std::begin(container), std::end(container), + [&f](const_ref a, const_ref b) { return f(a) < f(b); }); } // pointer to member function template -inline void sort(Container &c, R (S::*function)() const) +inline void sort(Container &container, R (S::*function)() const) { auto f = std::mem_fn(function); using const_ref = typename Container::const_reference; - std::sort(c.begin(), c.end(), [&f](const_ref a, const_ref b) { + std::sort(std::begin(container), std::end(container), + [&f](const_ref a, const_ref b) { return f(a) < f(b); }); } diff --git a/tests/auto/algorithm/tst_algorithm.cpp b/tests/auto/algorithm/tst_algorithm.cpp index 47e05b46362..9a227eb1b5c 100644 --- a/tests/auto/algorithm/tst_algorithm.cpp +++ b/tests/auto/algorithm/tst_algorithm.cpp @@ -25,6 +25,8 @@ #include +#include + #include class tst_Algorithm : public QObject @@ -151,6 +153,18 @@ void tst_Algorithm::sort() QList s6({&arr2[0], &arr2[1], &arr2[2]}); Utils::sort(s6, &Struct::member); QCOMPARE(s6, QList({&arr2[1], &arr2[2], &arr2[0]})); + // std::array: + std::array array = {{4, 10, 8, 1}}; + Utils::sort(array); + std::array arrayResult = {{1, 4, 8, 10}}; + QCOMPARE(array, arrayResult); + // valarray (no begin/end member functions): + std::valarray valarray(array.data(), array.size()); + std::valarray 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]); } QTEST_MAIN(tst_Algorithm)