From ab070f8f7e01fd2e7e549fb1108d2d08b9360dcc Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 7 Jul 2016 11:57:12 +0200 Subject: [PATCH] Algorithms: Simplify Utils::transform implementation Change-Id: I2c59254c3457d1e1f5152a779509069861d22543 Reviewed-by: Nikita Baryshnikov Reviewed-by: Tobias Hunger --- src/libs/utils/algorithm.h | 144 ++++++++++++++----------------------- 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index b1044d26e20..6ed0e9936c2 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -214,112 +214,78 @@ using decay_t = typename std::decay::type; template using result_of_t = typename std::result_of::type; -// abstraction to treat Container and QStringList similarly -template -struct ContainerType -{ +// Result type of transform operation -}; +template class Container, template class InputContainer, typename IT, typename Function> +using ResultContainer = Container>>; -// specialization for qt container T_Container -template class T_Container, typename T_Type> -struct ContainerType> -{ - template class C = T_Container> - using ResultOfTransform = C>>; - - template - using ResultOfTransformPMF = T_Container>; -}; - -// specialization for QStringList -template<> -struct ContainerType : ContainerType> -{ -}; - -} - -// actual implementation of transform -template // input container type -struct TransformImpl { - template - Q_REQUIRED_RESULT - static C call(const SC &container, F function) - { - C result; - std::transform(container.begin(), container.end(), - inserter(result), - function); - return result; - } - - template - Q_REQUIRED_RESULT - static C call(const SC &container, R (S::*p)() const) - { - return call(container, std::mem_fn(p)); - } - -}; - -// same container type for input and output, e.g. transforming a QList into QList -// or QStringList -> QList<> -template -Q_REQUIRED_RESULT -auto transform(const C &container, F function) --> typename ContainerType::template ResultOfTransform -{ - return TransformImpl< - typename ContainerType::template ResultOfTransform, - C - >::call(container, function); -} - -// same container type for member function pointer -template -Q_REQUIRED_RESULT -auto transform(const C &container, R (S::*p)() const) - ->typename ContainerType::template ResultOfTransformPMF -{ - return TransformImpl< - typename ContainerType::template ResultOfTransformPMF, - C - >::call(container, p); -} +} // anonymous // different container types for input and output, e.g. transforming a QList into a QSet template class C, // result container type - typename SC, // input container type + template class SC, // input container type + typename T, // input value type typename F> // function type Q_REQUIRED_RESULT -auto transform(const SC &container, F function) - -> typename ContainerType::template ResultOfTransform +auto transform(const SC &container, F function) -> ResultContainer { - return TransformImpl< - typename ContainerType::template ResultOfTransform, - SC - >::call(container, function); + ResultContainer result; + std::transform(container.begin(), container.end(), + inserter(result), + function); + return result; } // different container types for input and output, e.g. transforming a QList into a QSet // for member function pointers template class C, // result container type - typename SC, // input container type + template class SC, // input container type + typename T, // input value type typename R, typename S> Q_REQUIRED_RESULT -auto transform(const SC &container, R (S::*p)() const) - -> C> +auto transform(const SC &container, R (S::*p)() const) -> ResultContainer { - return TransformImpl< - C>, - SC - >::call(container, p); + return Utils::transform(container, std::mem_fn(p)); +} + +// same container type for input and output, e.g. transforming a QList into QList +// or QStringList -> QList<> +template class C, // container + typename T, // container value type + typename F> +Q_REQUIRED_RESULT +auto transform(const C &container, F function) -> ResultContainer +{ + return Utils::transform(container, function); +} + +// same container type for member function pointer +template class C, // container + typename T, // container value type + typename R, + typename S> +Q_REQUIRED_RESULT +auto transform(const C &container, R (S::*p)() const) -> ResultContainer +{ + return Utils::transform(container, std::mem_fn(p)); +} + +// QStringList different containers +template class C, // result container type + typename F> +Q_REQUIRED_RESULT +auto transform(const QStringList &container, F function) -> ResultContainer +{ + return Utils::transform(container, function); +} + +// QStringList -> QList +template +Q_REQUIRED_RESULT +auto transform(const QStringList &container, F function) -> ResultContainer +{ + return Utils::transform(container, function); } //////////////////