aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils/algorithm.h
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2017-12-01 11:22:58 +0100
committerTobias Hunger <tobias.hunger@qt.io>2017-12-01 14:41:15 +0000
commit2c09424c13a0bf4d63feca096d4170bca36293af (patch)
tree41d26d685eaab016f8135773f6ba81c8f32f4c23 /src/libs/utils/algorithm.h
parentb81d788793c4845782487cdd58eae3de82489261 (diff)
Utils: Clean up Utils::findOr and Utils::findOrDefault
Change-Id: I638e68480d3985b6df9a18aa96a067ee68484b12 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/libs/utils/algorithm.h')
-rw-r--r--src/libs/utils/algorithm.h129
1 files changed, 90 insertions, 39 deletions
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index bea1e00a81e..2ff8f3e524b 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -35,6 +35,8 @@
#include <QObject>
#include <QStringList>
+#include <memory>
+
namespace Utils
{
//////////////////
@@ -121,72 +123,120 @@ bool contains(const C<T, Args...> &container, R (S::*function)() const)
//////////////////
// findOr
/////////////////
-template<typename T, typename F>
-typename T::value_type findOr(const T &container, typename T::value_type other, F function)
+
+// Containers containing std::unique_ptr:
+template<template<typename, typename...> class C,
+ typename T, typename D,
+ typename F,
+ typename... Args>
+Q_REQUIRED_RESULT
+T *findOr(const C<std::unique_ptr<T, D>, Args...> &container, T *other, F function)
{
- typename T::const_iterator begin = std::begin(container);
- typename T::const_iterator end = std::end(container);
+ auto end = std::end(container);
+ auto it = std::find_if(std::begin(container), end, function);
+ return (it == end) ? other : it->get();
+}
- typename T::const_iterator it = std::find_if(begin, end, function);
- if (it == end)
- return other;
- return *it;
+template<template<typename, typename...> class C,
+ typename T, typename D,
+ typename R, typename S,
+ typename... Args>
+Q_REQUIRED_RESULT
+T *findOr(const C<std::unique_ptr<T, D>, Args...> &container, T *other, R (S::*function)() const)
+{
+ return findOr(container, other, std::mem_fn(function));
}
-// container of unique_ptr (with element_type and get()),
-// and with two template arguments like std::vector
-template<template<typename, typename> class C, typename AllocC, typename T, typename F>
-typename T::element_type *findOr(const C<T, AllocC> &container, typename T::element_type *other, F function)
+template<template<typename, typename...> class C, typename... Args,
+ typename T, typename D,
+ typename R, typename S>
+Q_REQUIRED_RESULT
+T *findOr(const C<std::unique_ptr<T, D>, Args...> &container, T *other, R S::*member)
{
- typename C<T, AllocC>::const_iterator begin = std::begin(container);
- typename C<T, AllocC>::const_iterator end = std::end(container);
+ return findOr(container, other, std::mem_fn(member));
+}
- typename C<T, AllocC>::const_iterator it = std::find_if(begin, end, function);
- if (it == end)
- return other;
- return it->get();
+template<typename C, typename F>
+Q_REQUIRED_RESULT
+typename C::value_type findOr(const C &container, typename C::value_type other, F function)
+{
+ typename C::const_iterator begin = std::begin(container);
+ typename C::const_iterator end = std::end(container);
+
+ typename C::const_iterator it = std::find_if(begin, end, function);
+ return it == end ? other : *it;
}
template<typename T, typename R, typename S>
+Q_REQUIRED_RESULT
typename T::value_type findOr(const T &container, typename T::value_type other, R (S::*function)() const)
{
return findOr(container, other, std::mem_fn(function));
}
-// container of unique_ptr (with element_type and get()),
-// and with two template arguments like std::vector
-template<template<typename, typename> class C, typename AllocC, typename T, typename R, typename S>
-typename T::element_type *findOr(const C<T, AllocC> &container, typename T::element_type *other, R (S::*function)() const)
+template<typename T, typename R, typename S>
+Q_REQUIRED_RESULT
+typename T::value_type findOr(const T &container, typename T::value_type other, R S::*member)
{
- return findOr(container, other, std::mem_fn(function));
+ return findOr(container, other, std::mem_fn(member));
}
-template<typename T, typename F>
-typename T::value_type findOrDefault(const T &container, F function)
+//////////////////
+// findOrDefault
+//////////////////
+
+// Containers containing std::unique_ptr:
+template<template<typename, typename...> class C,
+ typename T, typename D,
+ typename F,
+ typename... Args>
+Q_REQUIRED_RESULT
+T *findOrDefault(const C<std::unique_ptr<T, D>, Args...> &container, F function)
{
- return findOr(container, typename T::value_type(), function);
+ return findOr(container, static_cast<T*>(nullptr), function);
}
-template<typename T, typename R, typename S>
-typename T::value_type findOrDefault(const T &container, R (S::*function)() const)
+template<template<typename, typename...> class C,
+ typename T, typename D,
+ typename R, typename S,
+ typename... Args>
+Q_REQUIRED_RESULT
+T *findOrDefault(const C<std::unique_ptr<T, D>, Args...> &container, R (S::*function)() const)
{
- return findOr(container, typename T::value_type(), function);
+ return findOr(container, static_cast<T*>(nullptr), std::mem_fn(function));
}
-// container of unique_ptr (with element_type and get()),
-// and with two template arguments like std::vector
-template<template<typename, typename> class C, typename AllocC, typename T, typename F>
-typename T::element_type *findOrDefault(const C<T, AllocC> &container, F function)
+template<template<typename, typename...> class C,
+ typename T, typename D,
+ typename R, typename S,
+ typename... Args>
+Q_REQUIRED_RESULT
+T *findOrDefault(const C<std::unique_ptr<T, D>, Args...> &container, R S::*member)
{
- return findOr(container, nullptr, function);
+ return findOr(container, static_cast<T*>(nullptr), std::mem_fn(member));
}
-// container of unique_ptr (with element_type and get()),
-// and with two template arguments like std::vector
-template<template<typename, typename> class C, typename AllocC, typename T, typename R, typename S>
-typename T::element_type *findOrDefault(const C<T, AllocC> &container, R (S::*function)() const)
+
+// Default implementation:
+template<typename C, typename F>
+Q_REQUIRED_RESULT
+typename C::value_type findOrDefault(const C &container, F function)
+{
+ return findOr(container, typename C::value_type(), function);
+}
+
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT
+typename C::value_type findOrDefault(const C &container, R (S::*function)() const)
{
- return findOr(container, nullptr, std::mem_fn(function));
+ return findOr(container, typename C::value_type(), std::mem_fn(function));
+}
+
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT
+typename C::value_type findOrDefault(const C &container, R S::*member)
+{
+ return findOr(container, typename C::value_type(), std::mem_fn(member));
}
@@ -222,6 +272,7 @@ typename T::value_type maxElementOr(const T &container, typename T::value_type o
return *it;
}
+
//////////////////
// transform
/////////////////