diff options
author | Eike Ziller <eike.ziller@qt.io> | 2016-07-12 13:38:42 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2017-03-29 09:05:42 +0000 |
commit | 06250531dbea978aa4f0fd8af3f2f6a69b75d572 (patch) | |
tree | b26c8e3128a833a83f56f8206168f5af033172ad /src | |
parent | 163b2c027d25dfc5971f94ffcb24396fbf3dcf66 (diff) | |
download | qt-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')
-rw-r--r-- | src/libs/utils/algorithm.h | 132 |
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); } ////////////////// |