Commit 2c09424c authored by Tobias Hunger's avatar Tobias Hunger

Utils: Clean up Utils::findOr and Utils::findOrDefault

Change-Id: I638e68480d3985b6df9a18aa96a067ee68484b12
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
parent b81d7887
......@@ -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
/////////////////
......
......@@ -320,6 +320,15 @@ void tst_Algorithm::findOr()
Struct defS(6);
QCOMPARE(Utils::findOr(v3, &defS, &Struct::isOdd), v3.at(0).get());
QCOMPARE(Utils::findOr(v3, &defS, &Struct::isEven), &defS);
std::vector<std::shared_ptr<Struct>> v4;
v4.emplace_back(std::make_shared<Struct>(1));
v4.emplace_back(std::make_shared<Struct>(3));
v4.emplace_back(std::make_shared<Struct>(5));
v4.emplace_back(std::make_shared<Struct>(7));
std::shared_ptr<Struct> sharedDefS = std::make_shared<Struct>(6);
QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isOdd), v4.at(0));
QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isEven), sharedDefS);
}
void tst_Algorithm::findOrDefault()
......@@ -340,7 +349,15 @@ void tst_Algorithm::findOrDefault()
v3.emplace_back(std::make_unique<Struct>(5));
v3.emplace_back(std::make_unique<Struct>(7));
QCOMPARE(Utils::findOrDefault(v3, &Struct::isOdd), v3.at(0).get());
QCOMPARE(Utils::findOrDefault(v3, &Struct::isEven), static_cast<Struct*>(0));
QCOMPARE(Utils::findOrDefault(v3, &Struct::isEven), static_cast<Struct*>(nullptr));
std::vector<std::shared_ptr<Struct>> v4;
v4.emplace_back(std::make_shared<Struct>(1));
v4.emplace_back(std::make_shared<Struct>(3));
v4.emplace_back(std::make_shared<Struct>(5));
v4.emplace_back(std::make_shared<Struct>(7));
QCOMPARE(Utils::findOrDefault(v4, &Struct::isOdd), v4.at(0));
QCOMPARE(Utils::findOrDefault(v4, &Struct::isEven), std::shared_ptr<Struct>());
}
QTEST_MAIN(tst_Algorithm)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment