diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 8541e71ed1e..3a8bdbd84e9 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -205,118 +205,90 @@ inserter(QSet &container) return QSetInsertIterator>(container); } -// 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; - result.reserve(container.size()); - 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 -decltype(auto) transform(const C &container, F function) -{ - return TransformImpl< - typename ContainerType::template ResultOfTransform, - C - >::call(container, function); -} - -// same container type for member function pointer -template -Q_REQUIRED_RESULT -decltype(auto) transform(const C &container, R (S::*p)() const) -{ - return TransformImpl< - typename ContainerType::template ResultOfTransformPMF, - C - >::call(container, p); -} - -template -Q_REQUIRED_RESULT -decltype(auto) transform(const C &container, R S::*member) -{ - return transform(container, std::mem_fn(member)); -} +} // 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 -decltype(auto) transform(const SC &container, F function) +decltype(auto) transform(const SC &container, F function) { - return TransformImpl< - typename ContainerType::template ResultOfTransform, - SC - >::call(container, function); + ResultContainer result; + result.reserve(container.size()); + 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 -decltype(auto) transform(const SC &container, R (S::*p)() const) +decltype(auto) transform(const SC &container, R (S::*p)() const) { - return TransformImpl< - C>, - SC - >::call(container, p); + return 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 +decltype(auto) transform(const C &container, F function) +{ + return 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 +decltype(auto) transform(const C &container, R (S::*p)() const) +{ + return transform(container, std::mem_fn(p)); +} + +// same container type for members +template class C, // container + typename T, // container value type + typename R, + typename S> +Q_REQUIRED_RESULT +decltype(auto) transform(const C &container, R S::*member) +{ + return transform(container, std::mem_fn(member)); +} + +// QStringList different containers +template class C, // result container type + typename F> +Q_REQUIRED_RESULT +decltype(auto) transform(const QStringList &container, F function) +{ + return transform(container, function); +} + +// QStringList -> QList +template +Q_REQUIRED_RESULT +decltype(auto) transform(const QStringList &container, F function) +{ + return Utils::transform(container, function); } //////////////////