Wrap calls to Sequence::push_back
In C++11 push_back is overloaded to support rvalue-references, void std::vector<T>::push_back(const T &); void std::vector<T>::push_back(T &&); so attempting to get the address for push_back is ambiguous. Instead of hardcoding the function signature, the better and more general solution is to allow the compiler to do the required overload resolution itself, also allowing for implicit conversions to take place. Task-number: QTBUG-18996 Done-with: Liang Qi Reviewed-by: Olivier Goffart (cherry picked from commit ca34cc75294e0d2a8bc491a2c679fe8a69cd0408) Change-Id: Id271118e489f888905e491dd4cfc3d2db7697552 Reviewed-on: http://codereview.qt-project.org/4642 Reviewed-by: Liang Qi <liang.qi@nokia.com> Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
This commit is contained in:
parent
a13b17e42a
commit
0d4834c171
@ -102,10 +102,9 @@ namespace QtConcurrent {
|
||||
|
||||
namespace QtConcurrent {
|
||||
|
||||
template <typename Sequence, typename KeepFunctor, typename T, typename C, typename U>
|
||||
ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, T (C::*reduce)(U))
|
||||
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
|
||||
ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce)
|
||||
{
|
||||
typedef MemberFunctionWrapper1<T, C, U> ReduceFunctor;
|
||||
typedef typename Sequence::const_iterator Iterator;
|
||||
typedef FilterKernel<Sequence, KeepFunctor, ReduceFunctor> KernelType;
|
||||
return startThreadEngine(new KernelType(sequence, keep, reduce));
|
||||
@ -115,7 +114,7 @@ ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, T
|
||||
template <typename Sequence, typename KeepFunctor>
|
||||
QFuture<void> filter(Sequence &sequence, KeepFunctor keep)
|
||||
{
|
||||
return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back);
|
||||
return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper());
|
||||
}
|
||||
|
||||
// filteredReduced() on sequences
|
||||
@ -184,7 +183,7 @@ QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iter
|
||||
template <typename Sequence, typename KeepFunctor>
|
||||
void blockingFilter(Sequence &sequence, KeepFunctor keep)
|
||||
{
|
||||
filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back).startBlocking();
|
||||
filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()).startBlocking();
|
||||
}
|
||||
|
||||
// blocking filteredReduced() on sequences
|
||||
@ -246,18 +245,17 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered
|
||||
template <typename Sequence, typename KeepFunctor>
|
||||
Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep)
|
||||
{
|
||||
return blockingFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back, OrderedReduce);
|
||||
return startFilteredReduced<Sequence>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking();
|
||||
}
|
||||
|
||||
// blocking filtered() on iterators
|
||||
template <typename OutputSequence, typename Iterator, typename KeepFunctor>
|
||||
OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep)
|
||||
{
|
||||
return blockingFilteredReduced(begin,
|
||||
end,
|
||||
QtPrivate::createFunctionWrapper(keep),
|
||||
&OutputSequence::push_back,
|
||||
OrderedReduce);
|
||||
return startFilteredReduced<OutputSequence>(begin, end,
|
||||
QtPrivate::createFunctionWrapper(keep),
|
||||
QtPrivate::PushBackWrapper(),
|
||||
OrderedReduce).startBlocking();
|
||||
}
|
||||
|
||||
} // namespace QtConcurrent
|
||||
|
@ -195,6 +195,25 @@ QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func
|
||||
return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func);
|
||||
}
|
||||
|
||||
struct PushBackWrapper
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
template <class C, class U>
|
||||
inline void operator()(C &c, const U &u) const
|
||||
{
|
||||
return c.push_back(u);
|
||||
}
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
template <class C, class U>
|
||||
inline void operator()(C &c, U &&u) const
|
||||
{
|
||||
return c.push_back(u);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename Functor, bool foo = HasResultType<Functor>::Value>
|
||||
struct LazyResultType { typedef typename Functor::result_type Type; };
|
||||
template <typename Functor>
|
||||
|
@ -271,7 +271,7 @@ OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map)
|
||||
return blockingMappedReduced<OutputSequence>
|
||||
(sequence,
|
||||
QtPrivate::createFunctionWrapper(map),
|
||||
&OutputSequence::push_back,
|
||||
QtPrivate::PushBackWrapper(),
|
||||
QtConcurrent::OrderedReduce);
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType blockin
|
||||
return blockingMappedReduced<OutputSequence>
|
||||
(sequence,
|
||||
QtPrivate::createFunctionWrapper(map),
|
||||
&OutputSequence::push_back,
|
||||
QtPrivate::PushBackWrapper(),
|
||||
QtConcurrent::OrderedReduce);
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map)
|
||||
return blockingMappedReduced<Sequence>
|
||||
(begin, end,
|
||||
QtPrivate::createFunctionWrapper(map),
|
||||
&Sequence::push_back,
|
||||
QtPrivate::PushBackWrapper(),
|
||||
QtConcurrent::OrderedReduce);
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType blockingMapp
|
||||
return blockingMappedReduced<OutputSequence>
|
||||
(begin, end,
|
||||
QtPrivate::createFunctionWrapper(map),
|
||||
&OutputSequence::push_back,
|
||||
QtPrivate::PushBackWrapper(),
|
||||
QtConcurrent::OrderedReduce);
|
||||
}
|
||||
|
||||
|
@ -2320,11 +2320,6 @@ void tst_QtConcurrentMap::stlContainers()
|
||||
{
|
||||
#ifdef QT_NO_STL
|
||||
QSKIP("Qt compiled without STL support", SkipAll);
|
||||
#elif defined(Q_COMPILER_RVALUE_REFS)
|
||||
//mapped uses &Container::push_back, but in c++0x, std::vector has two overload of it
|
||||
// meaning it is not possible to take the address of that function anymore.
|
||||
QSKIP("mapped do not work with c++0x stl vector", SkipAll);
|
||||
#else
|
||||
std::vector<int> vector;
|
||||
vector.push_back(1);
|
||||
vector.push_back(2);
|
||||
|
Loading…
Reference in New Issue
Block a user