summaryrefslogtreecommitdiff
path: root/src/libs/utils
diff options
context:
space:
mode:
authorDaniel Teske <daniel.teske@digia.com>2014-07-07 19:02:26 +0200
committerDaniel Teske <daniel.teske@digia.com>2014-07-16 18:20:57 +0200
commiteccf1dc1e397303e218eaaf48977fd612cbd3d6a (patch)
tree0681cde5b07e72b5667820c7e4a14d2ff88f4ed1 /src/libs/utils
parent71b56d2b9c3264bd481915c763aac685c1ad24d0 (diff)
downloadqt-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.h70
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)
{