From 12ef434e40ebbebbd8ce7da7634456be6e0922ad Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 25 Feb 2016 16:55:58 +0100 Subject: [PATCH] mapReduce: Allow init and cleanup functions without future interface Change-Id: I49c5f66877db6f7a3b5d175e9ee333451b25d4de Reviewed-by: Tobias Hunger --- src/libs/utils/mapreduce.h | 41 +++++++++++++++++++++++--- tests/auto/mapreduce/tst_mapreduce.cpp | 40 +++++++++++++++---------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/libs/utils/mapreduce.h b/src/libs/utils/mapreduce.h index e4c3167f766..600686b2420 100644 --- a/src/libs/utils/mapreduce.h +++ b/src/libs/utils/mapreduce.h @@ -241,6 +241,32 @@ protected: }; +template +typename functionTraits::ResultType +callWithMaybeFutureInterfaceDispatch(std::false_type, QFutureInterface &, + Function &&function, Args&&... args) +{ + return function(std::forward(args)...); +} + +template +typename functionTraits::ResultType +callWithMaybeFutureInterfaceDispatch(std::true_type, QFutureInterface &futureInterface, + Function &&function, Args&&... args) +{ + return function(futureInterface, std::forward(args)...); +} + +template +typename functionTraits::ResultType +callWithMaybeFutureInterface(QFutureInterface &futureInterface, + Function &&function, Args&&... args) +{ + return callWithMaybeFutureInterfaceDispatch( + functionTakesArgument&>(), + futureInterface, std::forward(function), std::forward(args)...); +} + template void blockingIteratorMapReduce(QFutureInterface &futureInterface, ForwardIterator begin, ForwardIterator end, @@ -248,12 +274,14 @@ void blockingIteratorMapReduce(QFutureInterface &futureInterface, ReduceFunction &&reduce, CleanUpFunction &&cleanup, MapReduceOption option, int size) { - auto state = init(futureInterface); + auto state = callWithMaybeFutureInterface + (futureInterface, std::forward(init)); MapReduce::type, MapFunction, decltype(state), ReduceResult, ReduceFunction> mr(futureInterface, begin, end, std::forward(map), state, std::forward(reduce), option, size); mr.exec(); - cleanup(futureInterface, state); + callWithMaybeFutureInterface::type&> + (futureInterface, std::forward(cleanup), state); } template &futureInterfa } template -static void *dummyInit(QFutureInterface &) { return nullptr; } +static void *dummyInit() { return nullptr; } template struct DummyReduce { @@ -298,7 +326,7 @@ struct DummyReduce { }; template -static void dummyCleanup(QFutureInterface &, void *) { } +static void dummyCleanup(void *) { } } // Internal @@ -342,7 +370,10 @@ mapReduce(ForwardIterator begin, ForwardIterator end, InitFunction &&init, MapFu mapReduce. Container + StateType InitFunction(QFutureInterface&) + or + StateType InitFunction() void MapFunction(QFutureInterface&, const ItemType&) or @@ -353,6 +384,8 @@ mapReduce(ForwardIterator begin, ForwardIterator end, InitFunction &&init, MapFu ReduceResultType ReduceFunction(StateType&, const ItemType&) void CleanUpFunction(QFutureInterface&, StateType&) + or + void CleanUpFunction(StateType&) Notes: \list diff --git a/tests/auto/mapreduce/tst_mapreduce.cpp b/tests/auto/mapreduce/tst_mapreduce.cpp index 5c2a46c13b8..f84897662a1 100644 --- a/tests/auto/mapreduce/tst_mapreduce.cpp +++ b/tests/auto/mapreduce/tst_mapreduce.cpp @@ -58,11 +58,11 @@ static void returnxxThroughFutureInterface(QFutureInterface &fi, int x) void tst_MapReduce::mapReduce() { - const auto dummyInit = [](QFutureInterface& fi) -> double { + const auto initWithFutureInterface = [](QFutureInterface &fi) -> double { fi.reportResult(0.); return 0.; }; - const auto reduceWithFutureInterface = [](QFutureInterface& fi, double &state, int value) { + const auto reduceWithFutureInterface = [](QFutureInterface &fi, double &state, int value) { state += value; fi.reportResult(value); }; @@ -70,31 +70,31 @@ void tst_MapReduce::mapReduce() state += value; return value; }; - const auto cleanupHalfState = [](QFutureInterface &fi, double &state) { + const auto cleanupWithFutureInterface = [](QFutureInterface &fi, double &state) { state /= 2.; fi.reportResult(state); }; { QList results = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - dummyInit, returnxx, - reduceWithFutureInterface, cleanupHalfState) + initWithFutureInterface, returnxx, + reduceWithFutureInterface, cleanupWithFutureInterface) .results(); Utils::sort(results); // mapping order is undefined QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); } { QList results = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - dummyInit, returnxxThroughFutureInterface, - reduceWithFutureInterface, cleanupHalfState) + initWithFutureInterface, returnxxThroughFutureInterface, + reduceWithFutureInterface, cleanupWithFutureInterface) .results(); Utils::sort(results); // mapping order is undefined QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); } { QList results = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - dummyInit, returnxx, - reduceWithReturn, cleanupHalfState) + initWithFutureInterface, returnxx, + reduceWithReturn, cleanupWithFutureInterface) .results(); Utils::sort(results); // mapping order is undefined QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); @@ -103,21 +103,31 @@ void tst_MapReduce::mapReduce() // lvalue ref container QList container({1, 2, 3, 4, 5}); QList results = Utils::mapReduce(container, - dummyInit, returnxx, - reduceWithReturn, cleanupHalfState) + initWithFutureInterface, returnxx, + reduceWithReturn, cleanupWithFutureInterface) .results(); Utils::sort(results); // mapping order is undefined QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); } + { + // init and cleanup without future interface + QCOMPARE(Utils::mapReduce(QList({1, 2, 3}), + []() { return 0.; }, + [](int v) { return v*2; }, + [](double &state, int v) { return state += v/4.; }, + [](double &) { }, + Utils::MapReduceOption::Ordered).results(), + QList({.5, 1.5, 3.})); + } } void tst_MapReduce::mapReduceRvalueContainer() { { QFuture future = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - [](QFutureInterface&) { return 0; }, + []() { return 0; }, [](int value) { return value; }, - [](QFutureInterface&, int &state, int value) { state += value; }, + [](QFutureInterface &, int &state, int value) { state += value; }, [](QFutureInterface &fi, int &state) { fi.reportResult(state); }); // here, lifetime of the QList temporary ends QCOMPARE(future.results(), QList({15})); @@ -154,10 +164,10 @@ void tst_MapReduce::map() void tst_MapReduce::orderedMapReduce() { QCOMPARE(Utils::mapReduce(QList({1, 2, 3, 4}), - [](QFutureInterface &) { return 0; }, + []() { return 0; }, [](int i) { return i*2; }, [](int &state, int val) { state += val; return state; }, - [](QFutureInterface &, int &) { }, + [](int &) { }, Utils::MapReduceOption::Ordered).results(), QList({2, 6, 12, 20})); }