From: Andrii Grynenko Date: Fri, 13 Nov 2015 21:47:27 +0000 (-0800) Subject: Make collect work for types with no default constructors X-Git-Tag: deprecate-dynamic-initializer~255 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5bad4e9ff7c7bdca58b3e0c312b7f4f54dcea936;p=folly.git Make collect work for types with no default constructors Summary: This doesn't make the code less efficient, because RVO can't be used for CollectVariadicContext. Thus moving existing tuple vs constructing new tuple by moving all values from other tuple (where each value is wrapped in folly::Optional) should be pretty much the same. Reviewed By: hannesr Differential Revision: D2650293 fb-gh-sync-id: 648a358bf093a0bb9d058a997af9bf59014ad77c --- diff --git a/folly/futures/detail/Core.h b/folly/futures/detail/Core.h index bca540de..b0bb2ff7 100644 --- a/folly/futures/detail/Core.h +++ b/folly/futures/detail/Core.h @@ -410,18 +410,37 @@ struct CollectVariadicContext { p.setException(std::move(t.exception())); } } else if (!threw) { - std::get(results) = std::move(t.value()); + std::get(results) = std::move(t); } } ~CollectVariadicContext() { if (!threw.exchange(true)) { - p.setValue(std::move(results)); + p.setValue(unwrap(std::move(results))); } } Promise> p; - std::tuple results; + std::tuple...> results; std::atomic threw {false}; typedef Future> type; + + private: + template + static std::tuple unwrap(std::tuple...>&& o, + Ts2&&... ts2) { + static_assert(sizeof...(ts2) < + std::tuple_size...>>::value, + "Non-templated unwrap should be used instead"); + assert(std::get(o).hasValue()); + + return unwrap(std::move(o), + std::forward(ts2)..., + std::move(*std::get(o))); + } + + static std::tuple unwrap(std::tuple...>&& o, + Ts&&... ts) { + return std::tuple(std::forward(ts)...); + } }; template