From: Hannes Roth Date: Mon, 8 Jun 2015 20:07:01 +0000 (-0700) Subject: (Wangle) variadic collect X-Git-Tag: v0.45.0~6 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=db57efd05b6605784e1a8ed88bb20609352fe927;p=folly.git (Wangle) variadic collect Summary: For D2099047 (matthieu) and also for symmetry. Can re-use most of the code, also refactored it a bit (using an empty base case). Test Plan: Run all the tests. Will add some more before committing. Reviewed By: jsedgwick@fb.com Subscribers: folly-diffs@, jsedgwick, yfeldblum, chalfant, matthieu FB internal diff: D2131515 Signature: t1:2131515:1433776852:544166fbfdfabf6760fd78f87821290e17e6e4a3 --- diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index a63b2a80..4b2c7477 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -545,13 +545,13 @@ void mapSetCallback(InputIterator first, InputIterator last, F func) { // collectAll (variadic) template -typename detail::VariadicContext< +typename detail::CollectAllVariadicContext< typename std::decay::type::value_type...>::type collectAll(Fs&&... fs) { - auto ctx = std::make_shared::type::value_type...>>(); - detail::collectAllVariadicHelper(ctx, - std::forward::type>(fs)...); + detail::collectVariadicHelper( + ctx, std::forward::type>(fs)...); return ctx->p.getFuture(); } @@ -581,6 +581,8 @@ collectAll(InputIterator first, InputIterator last) { return ctx->p.getFuture(); } +// collect (iterator) + namespace detail { template @@ -648,6 +650,21 @@ collect(InputIterator first, InputIterator last) { return ctx->p.getFuture(); } +// collect (variadic) + +template +typename detail::CollectVariadicContext< + typename std::decay::type::value_type...>::type +collect(Fs&&... fs) { + auto ctx = std::make_shared::type::value_type...>>(); + detail::collectVariadicHelper( + ctx, std::forward::type>(fs)...); + return ctx->p.getFuture(); +} + +// collectAny (iterator) + template Future< std::pairp.getFuture(); } +// collectN (iterator) + template Future::value_type::value_type>>>> @@ -709,6 +728,8 @@ collectN(InputIterator first, InputIterator last, size_t n) { return ctx->p.getFuture(); } +// reduce (iterator) + template Future reduce(It first, It last, T&& initial, F&& func) { if (first == last) { @@ -740,6 +761,8 @@ Future reduce(It first, It last, T&& initial, F&& func) { return f; } +// window (collection) + template std::vector> window(Collection input, F func, size_t n) { @@ -787,6 +810,8 @@ window(Collection input, F func, size_t n) { return futures; } +// reduce + template template Future Future::reduce(I&& initial, F&& func) { @@ -801,6 +826,8 @@ Future Future::reduce(I&& initial, F&& func) { }); } +// unorderedReduce (iterator) + template Future unorderedReduce(It first, It last, T initial, F func) { if (first == last) { @@ -849,6 +876,8 @@ Future unorderedReduce(It first, It last, T initial, F func) { return ctx->promise_.getFuture(); } +// within + template Future Future::within(Duration dur, Timekeeper* tk) { return within(dur, TimedOut(), tk); @@ -890,6 +919,8 @@ Future Future::within(Duration dur, E e, Timekeeper* tk) { return ctx->promise.getFuture().via(getExecutor()); } +// delayed + template Future Future::delayed(Duration dur, Timekeeper* tk) { return collectAll(*this, futures::sleep(dur, tk)) diff --git a/folly/futures/Future-pre.h b/folly/futures/Future-pre.h index b7ee7b5c..f76c24ab 100644 --- a/folly/futures/Future-pre.h +++ b/folly/futures/Future-pre.h @@ -41,7 +41,8 @@ struct isTry> : std::true_type {}; namespace detail { template class Core; -template struct VariadicContext; +template struct CollectAllVariadicContext; +template struct CollectVariadicContext; template struct CollectContext; template diff --git a/folly/futures/detail/Core.h b/folly/futures/detail/Core.h index 34d0a725..de0173e7 100644 --- a/folly/futures/detail/Core.h +++ b/folly/futures/detail/Core.h @@ -341,34 +341,59 @@ class Core { }; template -struct VariadicContext { - VariadicContext() {} - ~VariadicContext() { +struct CollectAllVariadicContext { + CollectAllVariadicContext() {} + template + inline void setPartialResult(Try& t) { + std::get(results) = std::move(t); + } + ~CollectAllVariadicContext() { p.setValue(std::move(results)); } - Promise... >> p; - std::tuple... > results; + Promise...>> p; + std::tuple...> results; typedef Future...>> type; }; -template -typename std::enable_if::type -collectAllVariadicHelper(std::shared_ptr> ctx, - THead&& head, Fs&&... tail) { - head.setCallback_([ctx](Try&& t) { - std::get(ctx->results) = std::move(t); - }); +template +struct CollectVariadicContext { + CollectVariadicContext() {} + template + inline void setPartialResult(Try& t) { + if (t.hasException()) { + if (!threw.exchange(true)) { + p.setException(std::move(t.exception())); + } + } else if (!threw) { + std::get(results) = std::move(t.value()); + } + } + ~CollectVariadicContext() { + if (!threw.exchange(true)) { + p.setValue(std::move(results)); + } + } + Promise> p; + std::tuple results; + std::atomic threw; + typedef Future> type; +}; + +template