diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index c13a3a5bb61..6fc76f7d95b 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -150,11 +150,6 @@ auto equal(R S::*member, T value) ///////////////// namespace { -// needed for msvc 2010, that doesn't have a declval -// can be removed once we stop supporting it -template -T &&declval(); - ///////////////// // helper code for transform to use back_inserter and thus push_back for everything // and insert for QSet<> @@ -201,12 +196,9 @@ inserter(QSet &container) return QSetInsertIterator>(container); } -// helper: removes const, volatile and references from a type +// decay_t is C++14, so provide it here, remove once we require C++14 template -struct RemoveCvAndReference -{ - typedef typename std::remove_cv::type>::type type; -}; +using decay_t = typename std::decay::type; // abstraction to treat Container and QStringList similarly template @@ -225,19 +217,24 @@ struct ContainerType> { { typedef T_Container type; }; + + template class C = T_Container> + struct ResultOfTransform + { + typedef C::type>> type; + }; + + template + struct ResultOfTransformPMF + { + typedef typename WithElementType>::type type; + }; }; // specialization for QStringList template<> -struct ContainerType +struct ContainerType : ContainerType> { - typedef QString ElementType; - - template - struct WithElementType - { - typedef QList type; - }; }; } @@ -273,18 +270,10 @@ template Q_REQUIRED_RESULT auto transform(const C &container, F function) --> typename ContainerType::template WithElementType< // the type C - typename RemoveCvAndReference< // the return type of F stripped - decltype(declval()(declval::ElementType>())) // the return type of F - >::type - >::type +-> typename ContainerType::template ResultOfTransform::type { return TransformImpl< - typename ContainerType::template WithElementType< // the type C - typename RemoveCvAndReference< // the return type stripped - decltype(declval()(declval::ElementType>())) // the return type of F - >::type - >::type, + typename ContainerType::template ResultOfTransform::type, C >::call(container, function); } @@ -295,12 +284,10 @@ template Q_REQUIRED_RESULT auto transform(const C &container, R (S::*p)() const) - ->typename ContainerType::template WithElementType::type>::type + ->typename ContainerType::template ResultOfTransformPMF::type { return TransformImpl< - typename ContainerType::template WithElementType< // the type C - typename RemoveCvAndReference::type // stripped R - >::type, + typename ContainerType::template ResultOfTransformPMF::type, C >::call(container, p); } @@ -311,16 +298,10 @@ template class C, // result container type typename F> // function type Q_REQUIRED_RESULT auto transform(const SC &container, F function) - -> C< // container C - typename RemoveCvAndReference< // stripped return type of F - decltype(declval()(declval::ElementType>())) // return type of F - >::type> + -> typename ContainerType::template ResultOfTransform::type { return TransformImpl< - C< // result container type - typename RemoveCvAndReference< // stripped - decltype(declval()(declval::ElementType>())) // return type of F - >::type>, + typename ContainerType::template ResultOfTransform::type, SC >::call(container, function); } @@ -333,10 +314,10 @@ template class C, // result container type typename S> Q_REQUIRED_RESULT auto transform(const SC &container, R (S::*p)() const) - -> C::type> + -> C> { return TransformImpl< - C::type>, + C>, SC >::call(container, p); }