diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 6ed0e9936c2..b1044d26e20 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -214,78 +214,112 @@ using decay_t = typename std::decay::type; template using result_of_t = typename std::result_of::type; -// Result type of transform operation +// abstraction to treat Container and QStringList similarly +template +struct ContainerType +{ -template class Container, template class InputContainer, typename IT, typename Function> -using ResultContainer = Container>>; +}; -} // anonymous +// 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); +} // different container types for input and output, e.g. transforming a QList into a QSet template class C, // result container type - template class SC, // input container type - typename T, // input value type + typename SC, // input container type typename F> // function type Q_REQUIRED_RESULT -auto transform(const SC &container, F function) -> ResultContainer +auto transform(const SC &container, F function) + -> typename ContainerType::template ResultOfTransform { - ResultContainer result; - std::transform(container.begin(), container.end(), - inserter(result), - function); - return result; + return TransformImpl< + typename ContainerType::template ResultOfTransform, + SC + >::call(container, function); } // 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 - template class SC, // input container type - typename T, // input value type + typename SC, // input container type typename R, typename S> Q_REQUIRED_RESULT -auto transform(const SC &container, R (S::*p)() const) -> ResultContainer +auto transform(const SC &container, R (S::*p)() const) + -> C> { - 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); + return TransformImpl< + C>, + SC + >::call(container, p); } //////////////////