summaryrefslogtreecommitdiff
path: root/src/libs/utils/algorithm.h
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2016-07-12 13:38:42 +0200
committerEike Ziller <eike.ziller@qt.io>2017-03-29 09:05:42 +0000
commit06250531dbea978aa4f0fd8af3f2f6a69b75d572 (patch)
treeb26c8e3128a833a83f56f8206168f5af033172ad /src/libs/utils/algorithm.h
parent163b2c027d25dfc5971f94ffcb24396fbf3dcf66 (diff)
downloadqt-creator-06250531dbea978aa4f0fd8af3f2f6a69b75d572.tar.gz
Simplify Utils::transform (again)
Change-Id: I14690b55e9eeeac0aff243a6dfd6b83e7325179b Reviewed-by: Tobias Hunger <tobias.hunger@qt.io> Reviewed-by: Nikita Baryshnikov <nib952051@gmail.com>
Diffstat (limited to 'src/libs/utils/algorithm.h')
-rw-r--r--src/libs/utils/algorithm.h132
1 files changed, 52 insertions, 80 deletions
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index 8541e71ed1..3a8bdbd84e 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -205,118 +205,90 @@ inserter(QSet<X> &container)
return QSetInsertIterator<QSet<X>>(container);
}
-// abstraction to treat Container<T> and QStringList similarly
-template<typename T>
-struct ContainerType
-{
+// Result type of transform operation
-};
+template<template<typename> class Container, template<typename> class InputContainer, typename IT, typename Function>
+using ResultContainer = Container<std::decay_t<std::result_of_t<Function(IT)>>>;
-// specialization for qt container T_Container<T_Type>
-template<template<typename> class T_Container, typename T_Type>
-struct ContainerType<T_Container<T_Type>>
-{
- template<class F, template<typename> class C = T_Container>
- using ResultOfTransform = C<std::decay_t<std::result_of_t<F (T_Type)>>>;
-
- template<class R>
- using ResultOfTransformPMF = T_Container<std::decay_t<R>>;
-};
+} // anonymous
-// specialization for QStringList
-template<>
-struct ContainerType<QStringList> : ContainerType<QList<QString>>
+// different container types for input and output, e.g. transforming a QList into a QSet
+template<template<typename> class C, // result container type
+ template<typename> class SC, // input container type
+ typename T, // input value type
+ typename F> // function type
+Q_REQUIRED_RESULT
+decltype(auto) transform(const SC<T> &container, F function)
{
-};
-
+ ResultContainer<C, SC, T, F> result;
+ result.reserve(container.size());
+ std::transform(container.begin(), container.end(),
+ inserter(result),
+ function);
+ return result;
}
-// actual implementation of transform
-template<typename C, // result container type
- typename SC> // input container type
-struct TransformImpl {
- template <typename F>
- Q_REQUIRED_RESULT
- static C call(const SC &container, F function)
- {
- C result;
- result.reserve(container.size());
- std::transform(container.begin(), container.end(),
- inserter(result),
- function);
- return result;
- }
-
- template <typename R, typename S>
- Q_REQUIRED_RESULT
- static C call(const SC &container, R (S::*p)() const)
- {
- return call(container, std::mem_fn(p));
- }
-
-};
+// different container types for input and output, e.g. transforming a QList into a QSet
+// for member function pointers
+template<template<typename> class C, // result container type
+ template<typename> class SC, // input container type
+ typename T, // input value type
+ typename R,
+ typename S>
+Q_REQUIRED_RESULT
+decltype(auto) transform(const SC<T> &container, R (S::*p)() const)
+{
+ return transform<C, SC, T>(container, std::mem_fn(p));
+}
// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
// or QStringList -> QList<>
-template<typename C, // container
+template<template<typename> class C, // container
+ typename T, // container value type
typename F>
Q_REQUIRED_RESULT
-decltype(auto) transform(const C &container, F function)
+decltype(auto) transform(const C<T> &container, F function)
{
- return TransformImpl<
- typename ContainerType<C>::template ResultOfTransform<F>,
- C
- >::call(container, function);
+ return transform<C, C, T>(container, function);
}
// same container type for member function pointer
-template<typename C,
- typename R,
- typename S>
+template<template<typename> class C, // container
+ typename T, // container value type
+ typename R,
+ typename S>
Q_REQUIRED_RESULT
-decltype(auto) transform(const C &container, R (S::*p)() const)
+decltype(auto) transform(const C<T> &container, R (S::*p)() const)
{
- return TransformImpl<
- typename ContainerType<C>::template ResultOfTransformPMF<R>,
- C
- >::call(container, p);
+ return transform<C, C, T>(container, std::mem_fn(p));
}
-template<typename C,
+// same container type for members
+template<template<typename> class C, // container
+ typename T, // container value type
typename R,
typename S>
Q_REQUIRED_RESULT
-decltype(auto) transform(const C &container, R S::*member)
+decltype(auto) transform(const C<T> &container, R S::*member)
{
- return transform(container, std::mem_fn(member));
+ return transform<C, C, T>(container, std::mem_fn(member));
}
-// different container types for input and output, e.g. transforming a QList into a QSet
+// QStringList different containers
template<template<typename> class C, // result container type
- typename SC, // input container type
- typename F> // function type
+ typename F>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC &container, F function)
+decltype(auto) transform(const QStringList &container, F function)
{
- return TransformImpl<
- typename ContainerType<SC>::template ResultOfTransform<F, C>,
- SC
- >::call(container, function);
+ return transform<C, QList, QString>(container, function);
}
-// different container types for input and output, e.g. transforming a QList into a QSet
-// for member function pointers
-template<template<typename> class C, // result container type
- typename SC, // input container type
- typename R,
- typename S>
+// QStringList -> QList
+template<typename F>
Q_REQUIRED_RESULT
-decltype(auto) transform(const SC &container, R (S::*p)() const)
+decltype(auto) transform(const QStringList &container, F function)
{
- return TransformImpl<
- C<std::decay_t<R>>,
- SC
- >::call(container, p);
+ return Utils::transform<QList, QList, QString>(container, function);
}
//////////////////