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>
This commit is contained in:
Daniel Teske
2014-07-07 19:02:26 +02:00
parent 71b56d2b9c
commit eccf1dc1e3
29 changed files with 219 additions and 247 deletions

View File

@@ -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)
{