summaryrefslogtreecommitdiff
path: root/src/libs/utils/algorithm.h
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2017-12-16 20:39:33 +0100
committerEike Ziller <eike.ziller@qt.io>2017-12-19 07:35:38 +0000
commite0a23664aafad2a215df4c43e85a47c4a006e693 (patch)
tree84198ab253a1a8eb1325f1b0ab977a756239e9e4 /src/libs/utils/algorithm.h
parent479ab4ef22e8810f059307b9eca68b79893db7a4 (diff)
downloadqt-creator-e0a23664aafad2a215df4c43e85a47c4a006e693.tar.gz
Utils::transform: Allow usage with non-const source containers
Makes it possible to e.g. transform to list of reference_wrappers. Change-Id: Ib608034fc3f296824c289edd27563bc7a196ac6d Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/libs/utils/algorithm.h')
-rw-r--r--src/libs/utils/algorithm.h114
1 files changed, 71 insertions, 43 deletions
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index 7c6fad0d9a..90405f0129 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -334,11 +334,10 @@ inserter(QSet<X> &container)
// function without result type deduction:
template<typename ResultContainer, // complete result container type
- template<typename...> class SC, // input container type
- typename F, // function type
- typename... SCArgs> // Arguments to SC
+ typename SC, // input container type
+ typename F> // function type
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, F function)
+decltype(auto) transform(SC &&container, F function)
{
ResultContainer result;
result.reserve(container.size());
@@ -348,79 +347,74 @@ decltype(auto) transform(const SC<SCArgs...> &container, F function)
// function with result type deduction:
template<template<typename> class C, // result container type
- template<typename...> class SC, // input container type
+ typename SC, // input container type
typename F, // function type
- typename... SCArgs, // Arguments to SC
- typename Value = typename SC<SCArgs...>::value_type,
- typename ResultContainer = C<std::decay_t<std::result_of_t<F(Value)>>>>
+ typename Value = typename std::decay_t<SC>::value_type,
+ typename Result = std::decay_t<std::result_of_t<F(Value&)>>,
+ typename ResultContainer = C<Result>>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, F function)
+decltype(auto) transform(SC &&container, F function)
{
- return transform<ResultContainer>(container, function);
+ return transform<ResultContainer>(std::forward<SC>(container), function);
}
template<template<typename, typename> class C, // result container type
- template<typename...> class SC, // input container type
+ typename SC, // input container type
typename F, // function type
- typename... SCArgs, // Arguments to SC
- typename Value = typename SC<SCArgs...>::value_type,
- typename Result = std::decay_t<std::result_of_t<F(Value)>>,
+ typename Value = typename std::decay_t<SC>::value_type,
+ typename Result = std::decay_t<std::result_of_t<F(Value&)>>,
typename ResultContainer = C<Result, std::allocator<Result>>>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, F function)
+decltype(auto) transform(SC &&container, F function)
{
- return transform<ResultContainer>(container, function);
+ return transform<ResultContainer>(std::forward<SC>(container), function);
}
// member function without result type deduction:
template<template<typename...> class C, // result container type
- template<typename...> class SC, // input container type
+ typename SC, // input container type
typename R,
- typename S,
- typename... SCArgs> // Arguments to SC
+ typename S>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, R (S::*p)() const)
+decltype(auto) transform(SC &&container, R (S::*p)() const)
{
- return transform<C, SC>(container, std::mem_fn(p));
+ return transform<C>(std::forward<SC>(container), std::mem_fn(p));
}
// member function with result type deduction:
template<typename ResultContainer, // complete result container type
- template<typename...> class SC, // input container type
+ typename SC, // input container type
typename R,
- typename S,
- typename... SCArgs> // Arguments to SC
+ typename S>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, R (S::*p)() const)
+decltype(auto) transform(SC &&container, R (S::*p)() const)
{
- return transform<ResultContainer, SC>(container, std::mem_fn(p));
+ return transform<ResultContainer>(std::forward<SC>(container), std::mem_fn(p));
}
// member without result type deduction:
template<typename ResultContainer, // complete result container type
- template<typename...> class SC, // input container
+ typename SC, // input container
typename R,
- typename S,
- typename... SCArgs> // Arguments to SC
+ typename S>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, R S::*p)
+decltype(auto) transform(SC &&container, R S::*p)
{
- return transform<ResultContainer, SC>(container, std::mem_fn(p));
+ return transform<ResultContainer>(std::forward<SC>(container), std::mem_fn(p));
}
// member with result type deduction:
template<template<typename...> class C, // result container
- template<typename...> class SC, // input container
+ typename SC, // input container
typename R,
- typename S,
- typename... SCArgs> // Arguments to SC
+ typename S>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC<SCArgs...> &container, R S::*p)
+decltype(auto) transform(SC &&container, R S::*p)
{
- return transform<C, SC>(container, std::mem_fn(p));
+ return transform<C>(std::forward<SC>(container), std::mem_fn(p));
}
-// different container types for input and output, e.g. transforming a QList into a QSet
+// same container types for input and output, const input
// function:
template<template<typename...> class C, // container type
@@ -429,7 +423,7 @@ template<template<typename...> class C, // container type
Q_REQUIRED_RESULT
decltype(auto) transform(const C<CArgs...> &container, F function)
{
- return transform<C, C>(container, function);
+ return transform<C, const C<CArgs...> &>(container, function);
}
// member function:
@@ -440,7 +434,7 @@ template<template<typename...> class C, // container type
Q_REQUIRED_RESULT
decltype(auto) transform(const C<CArgs...> &container, R (S::*p)() const)
{
- return transform<C, C>(container, std::mem_fn(p));
+ return transform<C, const C<CArgs...> &>(container, std::mem_fn(p));
}
// members:
@@ -451,7 +445,41 @@ template<template<typename...> class C, // container
Q_REQUIRED_RESULT
decltype(auto) transform(const C<CArgs...> &container, R S::*p)
{
- return transform<C, C>(container, std::mem_fn(p));
+ return transform<C, const C<CArgs...> &>(container, std::mem_fn(p));
+}
+
+// same container types for input and output, non-const input
+
+// function:
+template<template<typename...> class C, // container type
+ typename F, // function type
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT
+decltype(auto) transform(C<CArgs...> &container, F function)
+{
+ return transform<C, C<CArgs...> &>(container, function);
+}
+
+// member function:
+template<template<typename...> class C, // container type
+ typename R,
+ typename S,
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT
+decltype(auto) transform(C<CArgs...> &container, R (S::*p)() const)
+{
+ return transform<C, C<CArgs...> &>(container, std::mem_fn(p));
+}
+
+// members:
+template<template<typename...> class C, // container
+ typename R,
+ typename S,
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT
+decltype(auto) transform(C<CArgs...> &container, R S::*p)
+{
+ return transform<C, C<CArgs...> &>(container, std::mem_fn(p));
}
// Specialization for QStringList:
@@ -461,7 +489,7 @@ template<template<typename...> class C = QList, // result container
Q_REQUIRED_RESULT
decltype(auto) transform(const QStringList &container, F function)
{
- return transform<C, QList>(static_cast<QList<QString>>(container), function);
+ return transform<C, const QList<QString> &>(static_cast<QList<QString>>(container), function);
}
// member function:
@@ -471,7 +499,7 @@ template<template<typename...> class C = QList, // result container type
Q_REQUIRED_RESULT
decltype(auto) transform(const QStringList &container, R (S::*p)() const)
{
- return transform<C, QList>(static_cast<QList<QString>>(container), std::mem_fn(p));
+ return transform<C, const QList<QString> &>(static_cast<QList<QString>>(container), std::mem_fn(p));
}
// members:
@@ -481,7 +509,7 @@ template<template<typename...> class C = QList, // result container
Q_REQUIRED_RESULT
decltype(auto) transform(const QStringList &container, R S::*p)
{
- return transform<C, QList>(static_cast<QList<QString>>(container), std::mem_fn(p));
+ return transform<C, const QList<QString> &>(static_cast<QList<QString>>(container), std::mem_fn(p));
}
//////////////////