diff options
author | Daniel Teske <daniel.teske@digia.com> | 2014-07-07 19:02:26 +0200 |
---|---|---|
committer | Daniel Teske <daniel.teske@digia.com> | 2014-07-16 18:20:57 +0200 |
commit | eccf1dc1e397303e218eaaf48977fd612cbd3d6a (patch) | |
tree | 0681cde5b07e72b5667820c7e4a14d2ff88f4ed1 /src/libs/utils | |
parent | 71b56d2b9c3264bd481915c763aac685c1ad24d0 (diff) | |
download | qt-creator-eccf1dc1e397303e218eaaf48977fd612cbd3d6a.tar.gz |
Even more algorithm usage in ProjectExplorer
Add Utils::transform and anyOf that take a member function pointer.
Remove bestElementOr it's unused.
Use declval<T> in transform's return type, because msvc does evaluate
T() and for types that don't have simple constructor this fails.
Add std::remove_reference since decltype returns a reference for
lvalues.
Change-Id: I22248b226748eeb27af0d300182d574438d7f756
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
Diffstat (limited to 'src/libs/utils')
-rw-r--r-- | src/libs/utils/algorithm.h | 70 |
1 files changed, 61 insertions, 9 deletions
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index c1cb7ea894..4fe91547f2 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -31,6 +31,7 @@ #define ALGORITHM_H #include <algorithm> +#include <functional> #if QT_VERSION < 0x050000 #ifndef Q_REQUIRED_RESULT @@ -46,6 +47,20 @@ namespace Utils { +////////////////// +// anyOf +///////////////// + +// anyOf taking a member function pointer +template<typename T, typename R, typename S> +bool anyOf(const T &container, R (S::*predicate)() const) +{ + static_assert(std::is_convertible<typename T::iterator::value_type, S *>::value + || std::is_convertible<typename T::iterator::value_type, S>::value, + "elements of the container must be convertible to the member function pointer's class."); + static_assert(std::is_convertible<R, bool>::value, "return type of predicate needs to be convertible to bool"); + return std::any_of(container.begin(), container.end(), std::mem_fn(predicate)); +} template<typename T, typename F> bool anyOf(const T &container, F predicate) @@ -53,12 +68,18 @@ bool anyOf(const T &container, F predicate) return std::any_of(container.begin(), container.end(), predicate); } +////////////////// +// allOf +///////////////// template<typename T, typename F> bool allOf(const T &container, F predicate) { return std::all_of(container.begin(), container.end(), predicate); } +////////////////// +// erase +///////////////// template<typename T, typename F> void erase(QList<T> &container, F predicate) { @@ -66,6 +87,9 @@ void erase(QList<T> &container, F predicate) container.end()); } +////////////////// +// contains +///////////////// template<typename T, typename F> bool contains(const T &container, F function) { @@ -76,6 +100,9 @@ bool contains(const T &container, F function) return it != end; } +////////////////// +// findOr +///////////////// template<typename T, typename F> typename T::value_type findOr(const T &container, typename T::value_type other, F function) { @@ -89,23 +116,45 @@ typename T::value_type findOr(const T &container, typename T::value_type other, } template<typename T, typename F> -typename T::value_type bestElementOr(const T &container, typename T::value_type other, F function) +typename T::value_type findOrDefault(const T &container, F function) { - typename T::const_iterator end = container.end(); - typename T::const_iterator begin = container.begin(); + return findOr(container, typename T::value_type(), function); +} - typename T::const_iterator it = std::min_element(begin, end, function); - if (it == end) - return other; - return *it; +////////////////// +// transform +///////////////// + +// transform taking a member function pointer +template<typename T, typename R, typename S> +Q_REQUIRED_RESULT +auto transform(const QList<T> &container, R (S::*p)() const) -> QList<R> +{ + static_assert(std::is_convertible<T, S *>::value + || std::is_convertible<T, S>::value, + "elements of container must be convertible to S"); + QList<R> result; + result.reserve(container.size()); + std::transform(container.begin(), container.end(), + std::back_inserter(result), + std::mem_fn(p)); + return result; +} + +namespace { +// needed for msvc 2010, that doesn't have a declval +// can be removed once we stop supporting it +template<typename T> +T &&declval(); } // Note: add overloads for other container types as needed template<typename T, typename F> Q_REQUIRED_RESULT -auto transform(const QList<T> &container, F function) -> QList<decltype(function(T()))> +auto transform(const QList<T> &container, F function) + -> QList<typename std::remove_reference<decltype(function(declval<T>()))>::type> { - QList<decltype(function(T()))> result; + QList<typename std::remove_reference<decltype(function(declval<T>()))>::type> result; result.reserve(container.size()); std::transform(container.begin(), container.end(), std::back_inserter(result), @@ -113,6 +162,9 @@ auto transform(const QList<T> &container, F function) -> QList<decltype(function return result; } +////////////////// +// sort +///////////////// template <typename Container> inline void sort(Container &c) { |