Commit c5cff936 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Avoid std::forward in folly/futures/

Summary: [Folly] Avoid `std::forward` in `folly/futures/` since function template instantiation is expensive at compile time and `std::forward` is, when used correctly, nothing more than library sugar for straightforward syntax.

Reviewed By: LeeHowes

Differential Revision: D22673234

fbshipit-source-id: f88bc8c8aa13797ae6eccf1a421a47ff135589e1
parent 28da027e
...@@ -96,7 +96,7 @@ struct InvokeResultWrapper<void> : InvokeResultWrapperBase<Try<Unit>> { ...@@ -96,7 +96,7 @@ struct InvokeResultWrapper<void> : InvokeResultWrapperBase<Try<Unit>> {
template <typename T, typename F> template <typename T, typename F>
auto wrapInvoke(folly::Try<T>&& t, F&& f) { auto wrapInvoke(folly::Try<T>&& t, F&& f) {
auto fn = [&]() { auto fn = [&]() {
return std::forward<F>(f)( return static_cast<F&&>(f)(
t.template get< t.template get<
false, false,
typename futures::detail::valueCallableResult<T, F>::FirstArg>()); typename futures::detail::valueCallableResult<T, F>::FirstArg>());
...@@ -118,14 +118,14 @@ class CoreCallbackState { ...@@ -118,14 +118,14 @@ class CoreCallbackState {
public: public:
CoreCallbackState(Promise<T>&& promise, F&& func) noexcept( CoreCallbackState(Promise<T>&& promise, F&& func) noexcept(
noexcept(DF(std::declval<F&&>()))) noexcept(DF(std::declval<F&&>())))
: func_(std::forward<F>(func)), promise_(std::move(promise)) { : func_(static_cast<F&&>(func)), promise_(std::move(promise)) {
assert(before_barrier()); assert(before_barrier());
} }
CoreCallbackState(CoreCallbackState&& that) noexcept( CoreCallbackState(CoreCallbackState&& that) noexcept(
noexcept(DF(std::declval<F&&>()))) { noexcept(DF(std::declval<F&&>()))) {
if (that.before_barrier()) { if (that.before_barrier()) {
new (&func_) DF(std::forward<F>(that.func_)); new (&func_) DF(static_cast<F&&>(that.func_));
promise_ = that.stealPromise(); promise_ = that.stealPromise();
} }
} }
...@@ -142,12 +142,12 @@ class CoreCallbackState { ...@@ -142,12 +142,12 @@ class CoreCallbackState {
auto invoke(Args&&... args) noexcept( auto invoke(Args&&... args) noexcept(
noexcept(std::declval<F&&>()(std::declval<Args&&>()...))) { noexcept(std::declval<F&&>()(std::declval<Args&&>()...))) {
assert(before_barrier()); assert(before_barrier());
return std::forward<F>(func_)(std::forward<Args>(args)...); return static_cast<F&&>(func_)(static_cast<Args&&>(args)...);
} }
template <typename... Args> template <typename... Args>
auto tryInvoke(Args&&... args) noexcept { auto tryInvoke(Args&&... args) noexcept {
return makeTryWith([&] { return invoke(std::forward<Args>(args)...); }); return makeTryWith([&] { return invoke(static_cast<Args&&>(args)...); });
} }
void setTry(Executor::KeepAlive<>&& keepAlive, Try<T>&& t) { void setTry(Executor::KeepAlive<>&& keepAlive, Try<T>&& t) {
...@@ -180,7 +180,7 @@ auto makeCoreCallbackState(Promise<T>&& p, F&& f) noexcept( ...@@ -180,7 +180,7 @@ auto makeCoreCallbackState(Promise<T>&& p, F&& f) noexcept(
noexcept(CoreCallbackState<T, F>( noexcept(CoreCallbackState<T, F>(
std::declval<Promise<T>&&>(), std::declval<Promise<T>&&>(),
std::declval<F&&>()))) { std::declval<F&&>()))) {
return CoreCallbackState<T, F>(std::move(p), std::forward<F>(f)); return CoreCallbackState<T, F>(std::move(p), static_cast<F&&>(f));
} }
template <typename T, typename R, typename... Args> template <typename T, typename R, typename... Args>
...@@ -201,7 +201,7 @@ FutureBase<T>::FutureBase(Future<T>&& other) noexcept : core_(other.core_) { ...@@ -201,7 +201,7 @@ FutureBase<T>::FutureBase(Future<T>&& other) noexcept : core_(other.core_) {
template <class T> template <class T>
template <class T2, typename> template <class T2, typename>
FutureBase<T>::FutureBase(T2&& val) FutureBase<T>::FutureBase(T2&& val)
: core_(Core::make(Try<T>(std::forward<T2>(val)))) {} : core_(Core::make(Try<T>(static_cast<T2&&>(val)))) {}
template <class T> template <class T>
template <typename T2> template <typename T2>
...@@ -316,7 +316,7 @@ void FutureBase<T>::setCallback_( ...@@ -316,7 +316,7 @@ void FutureBase<T>::setCallback_(
futures::detail::InlineContinuation allowInline) { futures::detail::InlineContinuation allowInline) {
throwIfContinued(); throwIfContinued();
getCore().setCallback( getCore().setCallback(
std::forward<F>(func), RequestContext::saveContext(), allowInline); static_cast<F&&>(func), RequestContext::saveContext(), allowInline);
} }
template <class T> template <class T>
...@@ -409,7 +409,7 @@ FutureBase<T>::thenImplementation( ...@@ -409,7 +409,7 @@ FutureBase<T>::thenImplementation(
*/ */
this->setCallback_( this->setCallback_(
[state = futures::detail::makeCoreCallbackState( [state = futures::detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))]( std::move(p), static_cast<F&&>(func))](
Executor::KeepAlive<>&& ka, Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, Try<T>&& t) mutable {
if (!R::Arg::isTry() && t.hasException()) { if (!R::Arg::isTry() && t.hasException()) {
state.setException(std::move(ka), std::move(t.exception())); state.setException(std::move(ka), std::move(t.exception()));
...@@ -464,7 +464,7 @@ FutureBase<T>::thenImplementation( ...@@ -464,7 +464,7 @@ FutureBase<T>::thenImplementation(
this->setCallback_( this->setCallback_(
[state = futures::detail::makeCoreCallbackState( [state = futures::detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))]( std::move(p), static_cast<F&&>(func))](
Executor::KeepAlive<>&& ka, Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, Try<T>&& t) mutable {
if (!R::Arg::isTry() && t.hasException()) { if (!R::Arg::isTry() && t.hasException()) {
state.setException(std::move(ka), std::move(t.exception())); state.setException(std::move(ka), std::move(t.exception()));
...@@ -603,7 +603,7 @@ struct WindowFakeVector { ...@@ -603,7 +603,7 @@ struct WindowFakeVector {
template <class T> template <class T>
SemiFuture<typename std::decay<T>::type> makeSemiFuture(T&& t) { SemiFuture<typename std::decay<T>::type> makeSemiFuture(T&& t) {
return makeSemiFuture(Try<typename std::decay<T>::type>(std::forward<T>(t))); return makeSemiFuture(Try<typename std::decay<T>::type>(static_cast<T&&>(t)));
} }
// makeSemiFutureWith(SemiFuture<T>()) -> SemiFuture<T> // makeSemiFutureWith(SemiFuture<T>()) -> SemiFuture<T>
...@@ -614,7 +614,7 @@ typename std::enable_if< ...@@ -614,7 +614,7 @@ typename std::enable_if<
makeSemiFutureWith(F&& func) { makeSemiFutureWith(F&& func) {
using InnerType = typename isFutureOrSemiFuture<invoke_result_t<F>>::Inner; using InnerType = typename isFutureOrSemiFuture<invoke_result_t<F>>::Inner;
try { try {
return std::forward<F>(func)(); return static_cast<F&&>(func)();
} catch (std::exception& e) { } catch (std::exception& e) {
return makeSemiFuture<InnerType>( return makeSemiFuture<InnerType>(
exception_wrapper(std::current_exception(), e)); exception_wrapper(std::current_exception(), e));
...@@ -633,7 +633,7 @@ typename std::enable_if< ...@@ -633,7 +633,7 @@ typename std::enable_if<
makeSemiFutureWith(F&& func) { makeSemiFutureWith(F&& func) {
using LiftedResult = lift_unit_t<invoke_result_t<F>>; using LiftedResult = lift_unit_t<invoke_result_t<F>>;
return makeSemiFuture<LiftedResult>( return makeSemiFuture<LiftedResult>(
makeTryWith([&func]() mutable { return std::forward<F>(func)(); })); makeTryWith([&func]() mutable { return static_cast<F&&>(func)(); }));
} }
template <class T> template <class T>
...@@ -772,7 +772,7 @@ SemiFuture<T>::defer(F&& func) && { ...@@ -772,7 +772,7 @@ SemiFuture<T>::defer(F&& func) && {
} }
}(); }();
auto sf = Future<T>(this->core_).thenTryInline(std::forward<F>(func)).semi(); auto sf = Future<T>(this->core_).thenTryInline(static_cast<F&&>(func)).semi();
this->core_ = nullptr; this->core_ = nullptr;
// Carry deferred executor through chain as constructor from Future will // Carry deferred executor through chain as constructor from Future will
// nullify it // nullify it
...@@ -798,11 +798,11 @@ SemiFuture<T>::deferExTry(F&& func) && { ...@@ -798,11 +798,11 @@ SemiFuture<T>::deferExTry(F&& func) && {
}(); }();
auto sf = Future<T>(this->core_) auto sf = Future<T>(this->core_)
.thenExTryInline([func = std::forward<F>(func)]( .thenExTryInline([func = static_cast<F&&>(func)](
folly::Executor::KeepAlive<>&& keepAlive, folly::Executor::KeepAlive<>&& keepAlive,
folly::Try<T>&& val) mutable { folly::Try<T>&& val) mutable {
return std::forward<F>(func)( return static_cast<F&&>(func)(
std::move(keepAlive), std::forward<decltype(val)>(val)); std::move(keepAlive), static_cast<decltype(val)>(val));
}) })
.semi(); .semi();
this->core_ = nullptr; this->core_ = nullptr;
...@@ -818,8 +818,8 @@ template <typename F> ...@@ -818,8 +818,8 @@ template <typename F>
SemiFuture<typename futures::detail::valueCallableResult<T, F>::value_type> SemiFuture<typename futures::detail::valueCallableResult<T, F>::value_type>
SemiFuture<T>::deferValue(F&& func) && { SemiFuture<T>::deferValue(F&& func) && {
return std::move(*this).defer( return std::move(*this).defer(
[f = std::forward<F>(func)](folly::Try<T>&& t) mutable { [f = static_cast<F&&>(func)](folly::Try<T>&& t) mutable {
return futures::detail::wrapInvoke(std::move(t), std::forward<F>(f)); return futures::detail::wrapInvoke(std::move(t), static_cast<F&&>(f));
}); });
} }
...@@ -829,9 +829,9 @@ SemiFuture< ...@@ -829,9 +829,9 @@ SemiFuture<
typename futures::detail::valueExecutorCallableResult<T, F>::value_type> typename futures::detail::valueExecutorCallableResult<T, F>::value_type>
SemiFuture<T>::deferExValue(F&& func) && { SemiFuture<T>::deferExValue(F&& func) && {
return std::move(*this).deferExTry( return std::move(*this).deferExTry(
[f = std::forward<F>(func)]( [f = static_cast<F&&>(func)](
folly::Executor::KeepAlive<> ka, folly::Try<T>&& t) mutable { folly::Executor::KeepAlive<> ka, folly::Try<T>&& t) mutable {
return std::forward<F>(f)( return static_cast<F&&>(f)(
ka, ka,
t.template get< t.template get<
false, false,
...@@ -844,10 +844,10 @@ template <class T> ...@@ -844,10 +844,10 @@ template <class T>
template <class ExceptionType, class F> template <class ExceptionType, class F>
SemiFuture<T> SemiFuture<T>::deferError(tag_t<ExceptionType>, F&& func) && { SemiFuture<T> SemiFuture<T>::deferError(tag_t<ExceptionType>, F&& func) && {
return std::move(*this).defer( return std::move(*this).defer(
[func = std::forward<F>(func)](Try<T>&& t) mutable { [func = static_cast<F&&>(func)](Try<T>&& t) mutable {
if (auto e = t.template tryGetExceptionObject<ExceptionType>()) { if (auto e = t.template tryGetExceptionObject<ExceptionType>()) {
return makeSemiFutureWith( return makeSemiFutureWith(
[&]() mutable { return std::forward<F>(func)(*e); }); [&]() mutable { return static_cast<F&&>(func)(*e); });
} else { } else {
return makeSemiFuture<T>(std::move(t)); return makeSemiFuture<T>(std::move(t));
} }
...@@ -858,10 +858,10 @@ template <class T> ...@@ -858,10 +858,10 @@ template <class T>
template <class F> template <class F>
SemiFuture<T> SemiFuture<T>::deferError(F&& func) && { SemiFuture<T> SemiFuture<T>::deferError(F&& func) && {
return std::move(*this).defer( return std::move(*this).defer(
[func = std::forward<F>(func)](Try<T> t) mutable { [func = static_cast<F&&>(func)](Try<T> t) mutable {
if (t.hasException()) { if (t.hasException()) {
return makeSemiFutureWith([&]() mutable { return makeSemiFutureWith([&]() mutable {
return std::forward<F>(func)(std::move(t.exception())); return static_cast<F&&>(func)(std::move(t.exception()));
}); });
} else { } else {
return makeSemiFuture<T>(std::move(t)); return makeSemiFuture<T>(std::move(t));
...@@ -971,10 +971,10 @@ template <class T> ...@@ -971,10 +971,10 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::tryCallableResult<T, F>::value_type> Future<typename futures::detail::tryCallableResult<T, F>::value_type>
Future<T>::thenTry(F&& func) && { Future<T>::thenTry(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
folly::Executor::KeepAlive<>&&, folly::Executor::KeepAlive<>&&,
folly::Try<T>&& t) mutable { folly::Try<T>&& t) mutable {
return std::forward<F>(f)(std::move(t)); return static_cast<F&&>(f)(std::move(t));
}; };
using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>; using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>;
return this->thenImplementation( return this->thenImplementation(
...@@ -985,10 +985,10 @@ template <class T> ...@@ -985,10 +985,10 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::tryCallableResult<T, F>::value_type> Future<typename futures::detail::tryCallableResult<T, F>::value_type>
Future<T>::thenTryInline(F&& func) && { Future<T>::thenTryInline(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
folly::Executor::KeepAlive<>&&, folly::Executor::KeepAlive<>&&,
folly::Try<T>&& t) mutable { folly::Try<T>&& t) mutable {
return std::forward<F>(f)(std::move(t)); return static_cast<F&&>(f)(std::move(t));
}; };
using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>; using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>;
return this->thenImplementation( return this->thenImplementation(
...@@ -999,11 +999,11 @@ template <class T> ...@@ -999,11 +999,11 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::tryExecutorCallableResult<T, F>::value_type> Future<typename futures::detail::tryExecutorCallableResult<T, F>::value_type>
Future<T>::thenExTry(F&& func) && { Future<T>::thenExTry(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable {
// Enforce that executor cannot be null // Enforce that executor cannot be null
DCHECK(ka); DCHECK(ka);
return std::forward<F>(f)(std::move(ka), std::move(t)); return static_cast<F&&>(f)(std::move(ka), std::move(t));
}; };
using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>; using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>;
return this->thenImplementation( return this->thenImplementation(
...@@ -1014,11 +1014,11 @@ template <class T> ...@@ -1014,11 +1014,11 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::tryExecutorCallableResult<T, F>::value_type> Future<typename futures::detail::tryExecutorCallableResult<T, F>::value_type>
Future<T>::thenExTryInline(F&& func) && { Future<T>::thenExTryInline(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable {
// Enforce that executor cannot be null // Enforce that executor cannot be null
DCHECK(ka); DCHECK(ka);
return std::forward<F>(f)(std::move(ka), std::move(t)); return static_cast<F&&>(f)(std::move(ka), std::move(t));
}; };
using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>; using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>;
return this->thenImplementation( return this->thenImplementation(
...@@ -1029,9 +1029,9 @@ template <class T> ...@@ -1029,9 +1029,9 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::valueCallableResult<T, F>::value_type> Future<typename futures::detail::valueCallableResult<T, F>::value_type>
Future<T>::thenValue(F&& func) && { Future<T>::thenValue(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
Executor::KeepAlive<>&&, folly::Try<T>&& t) mutable { Executor::KeepAlive<>&&, folly::Try<T>&& t) mutable {
return futures::detail::wrapInvoke(std::move(t), std::forward<F>(f)); return futures::detail::wrapInvoke(std::move(t), static_cast<F&&>(f));
}; };
using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>; using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>;
return this->thenImplementation( return this->thenImplementation(
...@@ -1042,9 +1042,9 @@ template <class T> ...@@ -1042,9 +1042,9 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::valueCallableResult<T, F>::value_type> Future<typename futures::detail::valueCallableResult<T, F>::value_type>
Future<T>::thenValueInline(F&& func) && { Future<T>::thenValueInline(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
Executor::KeepAlive<>&&, folly::Try<T>&& t) mutable { Executor::KeepAlive<>&&, folly::Try<T>&& t) mutable {
return futures::detail::wrapInvoke(std::move(t), std::forward<F>(f)); return futures::detail::wrapInvoke(std::move(t), static_cast<F&&>(f));
}; };
using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>; using R = futures::detail::tryExecutorCallableResult<T, decltype(lambdaFunc)>;
return this->thenImplementation( return this->thenImplementation(
...@@ -1055,11 +1055,11 @@ template <class T> ...@@ -1055,11 +1055,11 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::valueExecutorCallableResult<T, F>::value_type> Future<typename futures::detail::valueExecutorCallableResult<T, F>::value_type>
Future<T>::thenExValue(F&& func) && { Future<T>::thenExValue(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable {
// Enforce that executor cannot be null // Enforce that executor cannot be null
DCHECK(ka); DCHECK(ka);
return std::forward<F>(f)( return static_cast<F&&>(f)(
std::move(ka), std::move(ka),
t.template get< t.template get<
false, false,
...@@ -1075,11 +1075,11 @@ template <class T> ...@@ -1075,11 +1075,11 @@ template <class T>
template <typename F> template <typename F>
Future<typename futures::detail::valueExecutorCallableResult<T, F>::value_type> Future<typename futures::detail::valueExecutorCallableResult<T, F>::value_type>
Future<T>::thenExValueInline(F&& func) && { Future<T>::thenExValueInline(F&& func) && {
auto lambdaFunc = [f = std::forward<F>(func)]( auto lambdaFunc = [f = static_cast<F&&>(func)](
Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, folly::Try<T>&& t) mutable {
// Enforce that executor cannot be null // Enforce that executor cannot be null
DCHECK(ka); DCHECK(ka);
return std::forward<F>(f)( return static_cast<F&&>(f)(
std::move(ka), std::move(ka),
t.template get< t.template get<
false, false,
...@@ -1104,7 +1104,7 @@ Future<T>::thenError(tag_t<ExceptionType>, F&& func) && { ...@@ -1104,7 +1104,7 @@ Future<T>::thenError(tag_t<ExceptionType>, F&& func) && {
auto e = folly::getKeepAliveToken(ePtr ? *ePtr : InlineExecutor::instance()); auto e = folly::getKeepAliveToken(ePtr ? *ePtr : InlineExecutor::instance());
this->setCallback_([state = futures::detail::makeCoreCallbackState( this->setCallback_([state = futures::detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))]( std::move(p), static_cast<F&&>(func))](
Executor::KeepAlive<>&& ka, Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, Try<T>&& t) mutable {
if (auto ex = t.template tryGetExceptionObject< if (auto ex = t.template tryGetExceptionObject<
std::remove_reference_t<ExceptionType>>()) { std::remove_reference_t<ExceptionType>>()) {
...@@ -1139,7 +1139,7 @@ Future<T>::thenError(tag_t<ExceptionType>, F&& func) && { ...@@ -1139,7 +1139,7 @@ Future<T>::thenError(tag_t<ExceptionType>, F&& func) && {
auto e = folly::getKeepAliveToken(ePtr ? *ePtr : InlineExecutor::instance()); auto e = folly::getKeepAliveToken(ePtr ? *ePtr : InlineExecutor::instance());
this->setCallback_([state = futures::detail::makeCoreCallbackState( this->setCallback_([state = futures::detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))]( std::move(p), static_cast<F&&>(func))](
Executor::KeepAlive<>&& ka, Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, Try<T>&& t) mutable {
if (auto ex = t.template tryGetExceptionObject< if (auto ex = t.template tryGetExceptionObject<
std::remove_reference_t<ExceptionType>>()) { std::remove_reference_t<ExceptionType>>()) {
...@@ -1167,7 +1167,7 @@ Future<T>::thenError(F&& func) && { ...@@ -1167,7 +1167,7 @@ Future<T>::thenError(F&& func) && {
p.core_->initCopyInterruptHandlerFrom(this->getCore()); p.core_->initCopyInterruptHandlerFrom(this->getCore());
auto sf = p.getSemiFuture(); auto sf = p.getSemiFuture();
this->setCallback_([state = futures::detail::makeCoreCallbackState( this->setCallback_([state = futures::detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))]( std::move(p), static_cast<F&&>(func))](
Executor::KeepAlive<>&& ka, Try<T> t) mutable { Executor::KeepAlive<>&& ka, Try<T> t) mutable {
if (t.hasException()) { if (t.hasException()) {
auto tf2 = state.tryInvoke(std::move(t.exception())); auto tf2 = state.tryInvoke(std::move(t.exception()));
...@@ -1201,7 +1201,7 @@ Future<T>::thenError(F&& func) && { ...@@ -1201,7 +1201,7 @@ Future<T>::thenError(F&& func) && {
p.core_->initCopyInterruptHandlerFrom(this->getCore()); p.core_->initCopyInterruptHandlerFrom(this->getCore());
auto sf = p.getSemiFuture(); auto sf = p.getSemiFuture();
this->setCallback_([state = futures::detail::makeCoreCallbackState( this->setCallback_([state = futures::detail::makeCoreCallbackState(
std::move(p), std::forward<F>(func))]( std::move(p), static_cast<F&&>(func))](
Executor::KeepAlive<>&& ka, Try<T>&& t) mutable { Executor::KeepAlive<>&& ka, Try<T>&& t) mutable {
if (t.hasException()) { if (t.hasException()) {
state.setTry(std::move(ka), makeTryWith([&] { state.setTry(std::move(ka), makeTryWith([&] {
...@@ -1224,8 +1224,8 @@ template <class T> ...@@ -1224,8 +1224,8 @@ template <class T>
template <class F> template <class F>
Future<T> Future<T>::ensure(F&& func) && { Future<T> Future<T>::ensure(F&& func) && {
return std::move(*this).thenTry( return std::move(*this).thenTry(
[funcw = std::forward<F>(func)](Try<T>&& t) mutable { [funcw = static_cast<F&&>(func)](Try<T>&& t) mutable {
std::forward<F>(funcw)(); static_cast<F&&>(funcw)();
return makeFuture(std::move(t)); return makeFuture(std::move(t));
}); });
} }
...@@ -1236,8 +1236,8 @@ Future<T> ...@@ -1236,8 +1236,8 @@ Future<T>
Future<T>::onTimeout(HighResDuration dur, F&& func, Timekeeper* tk) && { Future<T>::onTimeout(HighResDuration dur, F&& func, Timekeeper* tk) && {
return std::move(*this).within(dur, tk).thenError( return std::move(*this).within(dur, tk).thenError(
tag_t<FutureTimeout>{}, tag_t<FutureTimeout>{},
[funcw = std::forward<F>(func)](auto const&) mutable { [funcw = static_cast<F&&>(func)](auto const&) mutable {
return std::forward<F>(funcw)(); return static_cast<F&&>(funcw)();
}); });
} }
...@@ -1245,8 +1245,8 @@ template <class Func> ...@@ -1245,8 +1245,8 @@ template <class Func>
auto via(Executor::KeepAlive<> x, Func&& func) -> Future< auto via(Executor::KeepAlive<> x, Func&& func) -> Future<
typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> { typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> {
return via(std::move(x)) return via(std::move(x))
.thenValue([f = std::forward<Func>(func)](auto&&) mutable { .thenValue([f = static_cast<Func&&>(func)](auto&&) mutable {
return std::forward<Func>(f)(); return static_cast<Func&&>(f)();
}); });
} }
...@@ -1254,7 +1254,7 @@ auto via(Executor::KeepAlive<> x, Func&& func) -> Future< ...@@ -1254,7 +1254,7 @@ auto via(Executor::KeepAlive<> x, Func&& func) -> Future<
template <class T> template <class T>
Future<typename std::decay<T>::type> makeFuture(T&& t) { Future<typename std::decay<T>::type> makeFuture(T&& t) {
return makeFuture(Try<typename std::decay<T>::type>(std::forward<T>(t))); return makeFuture(Try<typename std::decay<T>::type>(static_cast<T&&>(t)));
} }
inline Future<Unit> makeFuture() { inline Future<Unit> makeFuture() {
...@@ -1268,7 +1268,7 @@ typename std:: ...@@ -1268,7 +1268,7 @@ typename std::
makeFutureWith(F&& func) { makeFutureWith(F&& func) {
using InnerType = typename isFuture<invoke_result_t<F>>::Inner; using InnerType = typename isFuture<invoke_result_t<F>>::Inner;
try { try {
return std::forward<F>(func)(); return static_cast<F&&>(func)();
} catch (std::exception& e) { } catch (std::exception& e) {
return makeFuture<InnerType>( return makeFuture<InnerType>(
exception_wrapper(std::current_exception(), e)); exception_wrapper(std::current_exception(), e));
...@@ -1286,7 +1286,7 @@ typename std::enable_if< ...@@ -1286,7 +1286,7 @@ typename std::enable_if<
makeFutureWith(F&& func) { makeFutureWith(F&& func) {
using LiftedResult = lift_unit_t<invoke_result_t<F>>; using LiftedResult = lift_unit_t<invoke_result_t<F>>;
return makeFuture<LiftedResult>( return makeFuture<LiftedResult>(
makeTryWith([&func]() mutable { return std::forward<F>(func)(); })); makeTryWith([&func]() mutable { return static_cast<F&&>(func)(); }));
} }
template <class T> template <class T>
...@@ -1417,7 +1417,7 @@ collectAll(Fs&&... fs) { ...@@ -1417,7 +1417,7 @@ collectAll(Fs&&... fs) {
template <typename... Fs> template <typename... Fs>
Future<std::tuple<Try<typename remove_cvref_t<Fs>::value_type>...>> Future<std::tuple<Try<typename remove_cvref_t<Fs>::value_type>...>>
collectAllUnsafe(Fs&&... fs) { collectAllUnsafe(Fs&&... fs) {
return collectAll(std::forward<Fs>(fs)...).toUnsafeFuture(); return collectAll(static_cast<Fs&&>(fs)...).toUnsafeFuture();
} }
// collectAll (iterator) // collectAll (iterator)
...@@ -1591,7 +1591,7 @@ SemiFuture<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collect( ...@@ -1591,7 +1591,7 @@ SemiFuture<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collect(
template <typename... Fs> template <typename... Fs>
Future<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collectUnsafe( Future<std::tuple<typename remove_cvref_t<Fs>::value_type...>> collectUnsafe(
Fs&&... fs) { Fs&&... fs) {
return collect(std::forward<Fs>(fs)...).toUnsafeFuture(); return collect(static_cast<Fs&&>(fs)...).toUnsafeFuture();
} }
// collectAny (iterator) // collectAny (iterator)
...@@ -1760,7 +1760,7 @@ collectN(InputIterator first, InputIterator last, size_t n) { ...@@ -1760,7 +1760,7 @@ collectN(InputIterator first, InputIterator last, size_t n) {
template <class It, class T, class F> template <class It, class T, class F>
Future<T> reduce(It first, It last, T&& initial, F&& func) { Future<T> reduce(It first, It last, T&& initial, F&& func) {
if (first == last) { if (first == last) {
return makeFuture(std::forward<T>(initial)); return makeFuture(static_cast<T&&>(initial));
} }
typedef typename std::iterator_traits<It>::value_type::value_type ItT; typedef typename std::iterator_traits<It>::value_type::value_type ItT;
...@@ -1769,10 +1769,10 @@ Future<T> reduce(It first, It last, T&& initial, F&& func) { ...@@ -1769,10 +1769,10 @@ Future<T> reduce(It first, It last, T&& initial, F&& func) {
Arg; Arg;
typedef isTry<Arg> IsTry; typedef isTry<Arg> IsTry;
auto sfunc = std::make_shared<std::decay_t<F>>(std::forward<F>(func)); auto sfunc = std::make_shared<std::decay_t<F>>(static_cast<F&&>(func));
auto f = std::move(*first).thenTry( auto f = std::move(*first).thenTry(
[initial = std::forward<T>(initial), sfunc](Try<ItT>&& head) mutable { [initial = static_cast<T&&>(initial), sfunc](Try<ItT>&& head) mutable {
return (*sfunc)( return (*sfunc)(
std::move(initial), head.template get<IsTry::value, Arg&&>()); std::move(initial), head.template get<IsTry::value, Arg&&>());
}); });
...@@ -1866,8 +1866,8 @@ template <class T> ...@@ -1866,8 +1866,8 @@ template <class T>
template <class I, class F> template <class I, class F>
Future<I> Future<T>::reduce(I&& initial, F&& func) && { Future<I> Future<T>::reduce(I&& initial, F&& func) && {
return std::move(*this).thenValue( return std::move(*this).thenValue(
[minitial = std::forward<I>(initial), [minitial = static_cast<I&&>(initial),
mfunc = std::forward<F>(func)](T&& vals) mutable { mfunc = static_cast<F&&>(func)](T&& vals) mutable {
auto ret = std::move(minitial); auto ret = std::move(minitial);
for (auto& val : vals) { for (auto& val : vals) {
ret = mfunc(std::move(ret), std::move(val)); ret = mfunc(std::move(ret), std::move(val));
...@@ -2429,7 +2429,7 @@ Future<bool> Future<T>::willEqual(Future<T>& f) { ...@@ -2429,7 +2429,7 @@ Future<bool> Future<T>::willEqual(Future<T>& f) {
template <class T> template <class T>
template <class F> template <class F>
Future<T> Future<T>::filter(F&& predicate) && { Future<T> Future<T>::filter(F&& predicate) && {
return std::move(*this).thenValue([p = std::forward<F>(predicate)](T val) { return std::move(*this).thenValue([p = static_cast<F&&>(predicate)](T val) {
T const& valConstRef = val; T const& valConstRef = val;
if (!p(valConstRef)) { if (!p(valConstRef)) {
throw_exception<FuturePredicateDoesNotObtain>(); throw_exception<FuturePredicateDoesNotObtain>();
...@@ -2441,7 +2441,7 @@ Future<T> Future<T>::filter(F&& predicate) && { ...@@ -2441,7 +2441,7 @@ Future<T> Future<T>::filter(F&& predicate) && {
template <class F> template <class F>
auto when(bool p, F&& thunk) auto when(bool p, F&& thunk)
-> decltype(std::declval<invoke_result_t<F>>().unit()) { -> decltype(std::declval<invoke_result_t<F>>().unit()) {
return p ? std::forward<F>(thunk)().unit() : makeFuture(); return p ? static_cast<F&&>(thunk)().unit() : makeFuture();
} }
template <class P, class F> template <class P, class F>
...@@ -2451,9 +2451,9 @@ typename std:: ...@@ -2451,9 +2451,9 @@ typename std::
if (predicate()) { if (predicate()) {
auto future = thunk(); auto future = thunk();
return std::move(future).deferExValue( return std::move(future).deferExValue(
[predicate = std::forward<P>(predicate), [predicate = static_cast<P&&>(predicate),
thunk = std::forward<F>(thunk)](auto&& ex, auto&&) mutable { thunk = static_cast<F&&>(thunk)](auto&& ex, auto&&) mutable {
return whileDo(std::forward<P>(predicate), std::forward<F>(thunk)) return whileDo(static_cast<P&&>(predicate), static_cast<F&&>(thunk))
.via(std::move(ex)); .via(std::move(ex));
}); });
} }
...@@ -2466,9 +2466,9 @@ whileDo(P&& predicate, F&& thunk) { ...@@ -2466,9 +2466,9 @@ whileDo(P&& predicate, F&& thunk) {
if (predicate()) { if (predicate()) {
auto future = thunk(); auto future = thunk();
return std::move(future).thenValue( return std::move(future).thenValue(
[predicate = std::forward<P>(predicate), [predicate = static_cast<P&&>(predicate),
thunk = std::forward<F>(thunk)](auto&&) mutable { thunk = static_cast<F&&>(thunk)](auto&&) mutable {
return whileDo(std::forward<P>(predicate), std::forward<F>(thunk)); return whileDo(static_cast<P&&>(predicate), static_cast<F&&>(thunk));
}); });
} }
return makeFuture(); return makeFuture();
...@@ -2480,7 +2480,7 @@ auto times(const int n, F&& thunk) { ...@@ -2480,7 +2480,7 @@ auto times(const int n, F&& thunk) {
[n, count = std::make_unique<std::atomic<int>>(0)]() mutable { [n, count = std::make_unique<std::atomic<int>>(0)]() mutable {
return count->fetch_add(1, std::memory_order_relaxed) < n; return count->fetch_add(1, std::memory_order_relaxed) < n;
}, },
std::forward<F>(thunk)); static_cast<F&&>(thunk));
} }
namespace futures { namespace futures {
...@@ -2529,8 +2529,8 @@ mapTry(Executor& exec, It first, It last, F func, int) { ...@@ -2529,8 +2529,8 @@ mapTry(Executor& exec, It first, It last, F func, int) {
template <typename F, class Ensure> template <typename F, class Ensure>
auto ensure(F&& f, Ensure&& ensure) { auto ensure(F&& f, Ensure&& ensure) {
return makeSemiFuture() return makeSemiFuture()
.deferValue([f = std::forward<F>(f)](auto) mutable { return f(); }) .deferValue([f = static_cast<F&&>(f)](auto) mutable { return f(); })
.defer([ensure = std::forward<Ensure>(ensure)](auto resultTry) mutable { .defer([ensure = static_cast<Ensure&&>(ensure)](auto resultTry) mutable {
ensure(); ensure();
return std::move(resultTry).value(); return std::move(resultTry).value();
}); });
......
...@@ -222,8 +222,8 @@ auto makeExecutorLambda( ...@@ -222,8 +222,8 @@ auto makeExecutorLambda(
F&& func, F&& func,
typename std::enable_if<is_invocable_v<F>, int>::type = 0) { typename std::enable_if<is_invocable_v<F>, int>::type = 0) {
return return
[func = std::forward<F>(func)](Executor::KeepAlive<>&&, auto&&) mutable { [func = static_cast<F&&>(func)](Executor::KeepAlive<>&&, auto&&) mutable {
return std::forward<F>(func)(); return static_cast<F&&>(func)();
}; };
} }
...@@ -232,10 +232,10 @@ auto makeExecutorLambda( ...@@ -232,10 +232,10 @@ auto makeExecutorLambda(
F&& func, F&& func,
typename std::enable_if<!is_invocable_v<F>, int>::type = 0) { typename std::enable_if<!is_invocable_v<F>, int>::type = 0) {
using R = futures::detail::callableResult<T, F&&>; using R = futures::detail::callableResult<T, F&&>;
return [func = std::forward<F>(func)]( return [func = static_cast<F&&>(func)](
Executor::KeepAlive<>&&, Executor::KeepAlive<>&&,
typename R::Arg::ArgList::FirstArg&& param) mutable { typename R::Arg::ArgList::FirstArg&& param) mutable {
return std::forward<F>(func)(std::forward<decltype(param)>(param)); return static_cast<F&&>(func)(static_cast<decltype(param)>(param));
}; };
} }
......
...@@ -157,7 +157,7 @@ class FutureBase { ...@@ -157,7 +157,7 @@ class FutureBase {
typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
type = 0> type = 0>
explicit FutureBase(in_place_t, Args&&... args) explicit FutureBase(in_place_t, Args&&... args)
: core_(Core::make(in_place, std::forward<Args>(args)...)) {} : core_(Core::make(in_place, static_cast<Args&&>(args)...)) {}
FutureBase(FutureBase<T> const&) = delete; FutureBase(FutureBase<T> const&) = delete;
FutureBase(SemiFuture<T>&&) noexcept; FutureBase(SemiFuture<T>&&) noexcept;
...@@ -344,7 +344,7 @@ class FutureBase { ...@@ -344,7 +344,7 @@ class FutureBase {
template <class E> template <class E>
void raise(E&& exception) { void raise(E&& exception) {
raise(make_exception_wrapper<typename std::remove_reference<E>::type>( raise(make_exception_wrapper<typename std::remove_reference<E>::type>(
std::forward<E>(exception))); static_cast<E&&>(exception)));
} }
/// Raises a FutureCancellation interrupt. /// Raises a FutureCancellation interrupt.
...@@ -530,7 +530,7 @@ class SemiFuture : private futures::detail::FutureBase<T> { ...@@ -530,7 +530,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
!isFuture<typename std::decay<T2>::type>::value && !isFuture<typename std::decay<T2>::type>::value &&
!isSemiFuture<typename std::decay<T2>::type>::value && !isSemiFuture<typename std::decay<T2>::type>::value &&
std::is_constructible<Try<T>, T2>::value>::type> std::is_constructible<Try<T>, T2>::value>::type>
/* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {} /* implicit */ SemiFuture(T2&& val) : Base(static_cast<T2&&>(val)) {}
/// Construct a (logical) SemiFuture-of-void. /// Construct a (logical) SemiFuture-of-void.
/// ///
...@@ -558,7 +558,7 @@ class SemiFuture : private futures::detail::FutureBase<T> { ...@@ -558,7 +558,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
type = 0> type = 0>
explicit SemiFuture(in_place_t, Args&&... args) explicit SemiFuture(in_place_t, Args&&... args)
: Base(in_place, std::forward<Args>(args)...) {} : Base(in_place, static_cast<Args&&>(args)...) {}
SemiFuture(SemiFuture<T> const&) = delete; SemiFuture(SemiFuture<T> const&) = delete;
// movable // movable
...@@ -802,7 +802,7 @@ class SemiFuture : private futures::detail::FutureBase<T> { ...@@ -802,7 +802,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
template <class ExceptionType, class F> template <class ExceptionType, class F>
SemiFuture<T> deferError(F&& func) && { SemiFuture<T> deferError(F&& func) && {
return std::move(*this).deferError( return std::move(*this).deferError(
tag_t<ExceptionType>{}, std::forward<F>(func)); tag_t<ExceptionType>{}, static_cast<F&&>(func));
} }
/// Set an error continuation for this SemiFuture where the continuation can /// Set an error continuation for this SemiFuture where the continuation can
...@@ -1034,7 +1034,7 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -1034,7 +1034,7 @@ class Future : private futures::detail::FutureBase<T> {
!isFuture<typename std::decay<T2>::type>::value && !isFuture<typename std::decay<T2>::type>::value &&
!isSemiFuture<typename std::decay<T2>::type>::value && !isSemiFuture<typename std::decay<T2>::type>::value &&
std::is_constructible<Try<T>, T2>::value>::type> std::is_constructible<Try<T>, T2>::value>::type>
/* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {} /* implicit */ Future(T2&& val) : Base(static_cast<T2&&>(val)) {}
/// Construct a (logical) Future-of-void. /// Construct a (logical) Future-of-void.
/// ///
...@@ -1062,7 +1062,7 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -1062,7 +1062,7 @@ class Future : private futures::detail::FutureBase<T> {
typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
type = 0> type = 0>
explicit Future(in_place_t, Args&&... args) explicit Future(in_place_t, Args&&... args)
: Base(in_place, std::forward<Args>(args)...) {} : Base(in_place, static_cast<Args&&>(args)...) {}
Future(Future<T> const&) = delete; Future(Future<T> const&) = delete;
// movable // movable
...@@ -1225,12 +1225,12 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -1225,12 +1225,12 @@ class Future : private futures::detail::FutureBase<T> {
template <typename F> template <typename F>
Future<typename futures::detail::tryCallableResult<T, F>::value_type> then( Future<typename futures::detail::tryCallableResult<T, F>::value_type> then(
F&& func) && { F&& func) && {
return std::move(*this).thenTry(std::forward<F>(func)); return std::move(*this).thenTry(static_cast<F&&>(func));
} }
template <typename F> template <typename F>
Future<typename futures::detail::tryCallableResult<T, F>::value_type> Future<typename futures::detail::tryCallableResult<T, F>::value_type>
thenInline(F&& func) && { thenInline(F&& func) && {
return std::move(*this).thenTryInline(std::forward<F>(func)); return std::move(*this).thenTryInline(static_cast<F&&>(func));
} }
/// Variant where func is an member function /// Variant where func is an member function
...@@ -1435,7 +1435,7 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -1435,7 +1435,7 @@ class Future : private futures::detail::FutureBase<T> {
template <class ExceptionType, class F> template <class ExceptionType, class F>
Future<T> thenError(F&& func) && { Future<T> thenError(F&& func) && {
return std::move(*this).thenError( return std::move(*this).thenError(
tag_t<ExceptionType>{}, std::forward<F>(func)); tag_t<ExceptionType>{}, static_cast<F&&>(func));
} }
/// Set an error continuation for this Future where the continuation can /// Set an error continuation for this Future where the continuation can
...@@ -2014,13 +2014,13 @@ std::pair<Promise<T>, Future<T>> makePromiseContract(Executor::KeepAlive<> e) { ...@@ -2014,13 +2014,13 @@ std::pair<Promise<T>, Future<T>> makePromiseContract(Executor::KeepAlive<> e) {
template <class F> template <class F>
auto makeAsyncTask(folly::Executor::KeepAlive<> ka, F&& func) { auto makeAsyncTask(folly::Executor::KeepAlive<> ka, F&& func) {
return [func = std::forward<F>(func), return [func = static_cast<F&&>(func),
ka = std::move(ka)](auto&& param) mutable { ka = std::move(ka)](auto&& param) mutable {
return via( return via(
ka, ka,
[func = std::move(func), [func = std::move(func),
param = std::forward<decltype(param)>(param)]() mutable { param = static_cast<decltype(param)>(param)]() mutable {
return std::forward<F>(func)(std::forward<decltype(param)>(param)); return static_cast<F&&>(func)(static_cast<decltype(param)&&>(param));
}); });
}; };
} }
...@@ -2115,26 +2115,26 @@ mapTry(Executor& exec, It first, It last, F func, int = 0); ...@@ -2115,26 +2115,26 @@ mapTry(Executor& exec, It first, It last, F func, int = 0);
template <class Collection, class F> template <class Collection, class F>
auto mapValue(Collection&& c, F&& func) auto mapValue(Collection&& c, F&& func)
-> decltype(mapValue(c.begin(), c.end(), func)) { -> decltype(mapValue(c.begin(), c.end(), func)) {
return mapValue(c.begin(), c.end(), std::forward<F>(func)); return mapValue(c.begin(), c.end(), static_cast<F&&>(func));
} }
template <class Collection, class F> template <class Collection, class F>
auto mapTry(Collection&& c, F&& func) auto mapTry(Collection&& c, F&& func)
-> decltype(mapTry(c.begin(), c.end(), func)) { -> decltype(mapTry(c.begin(), c.end(), func)) {
return mapTry(c.begin(), c.end(), std::forward<F>(func)); return mapTry(c.begin(), c.end(), static_cast<F&&>(func));
} }
// Sugar for the most common case // Sugar for the most common case
template <class Collection, class F> template <class Collection, class F>
auto mapValue(Executor& exec, Collection&& c, F&& func) auto mapValue(Executor& exec, Collection&& c, F&& func)
-> decltype(mapValue(exec, c.begin(), c.end(), func)) { -> decltype(mapValue(exec, c.begin(), c.end(), func)) {
return mapValue(exec, c.begin(), c.end(), std::forward<F>(func)); return mapValue(exec, c.begin(), c.end(), static_cast<F&&>(func));
} }
template <class Collection, class F> template <class Collection, class F>
auto mapTry(Executor& exec, Collection&& c, F&& func) auto mapTry(Executor& exec, Collection&& c, F&& func)
-> decltype(mapTry(exec, c.begin(), c.end(), func)) { -> decltype(mapTry(exec, c.begin(), c.end(), func)) {
return mapTry(exec, c.begin(), c.end(), std::forward<F>(func)); return mapTry(exec, c.begin(), c.end(), static_cast<F&&>(func));
} }
/// Carry out the computation contained in the given future if /// Carry out the computation contained in the given future if
...@@ -2544,10 +2544,10 @@ template <class Collection, class T, class F> ...@@ -2544,10 +2544,10 @@ template <class Collection, class T, class F>
auto reduce(Collection&& c, T&& initial, F&& func) -> decltype(folly::reduce( auto reduce(Collection&& c, T&& initial, F&& func) -> decltype(folly::reduce(
c.begin(), c.begin(),
c.end(), c.end(),
std::forward<T>(initial), static_cast<T&&>(initial),
std::forward<F>(func))) { static_cast<F&&>(func))) {
return folly::reduce( return folly::reduce(
c.begin(), c.end(), std::forward<T>(initial), std::forward<F>(func)); c.begin(), c.end(), static_cast<T&&>(initial), static_cast<F&&>(func));
} }
/** like reduce, but calls func on finished futures as they complete /** like reduce, but calls func on finished futures as they complete
...@@ -2562,10 +2562,10 @@ auto unorderedReduce(Collection&& c, T&& initial, F&& func) ...@@ -2562,10 +2562,10 @@ auto unorderedReduce(Collection&& c, T&& initial, F&& func)
-> decltype(folly::unorderedReduce( -> decltype(folly::unorderedReduce(
c.begin(), c.begin(),
c.end(), c.end(),
std::forward<T>(initial), static_cast<T&&>(initial),
std::forward<F>(func))) { static_cast<F&&>(func))) {
return folly::unorderedReduce( return folly::unorderedReduce(
c.begin(), c.end(), std::forward<T>(initial), std::forward<F>(func)); c.begin(), c.end(), static_cast<T&&>(initial), static_cast<F&&>(func));
} }
/// Carry out the computation contained in the given future if /// Carry out the computation contained in the given future if
......
...@@ -121,7 +121,7 @@ void Promise<T>::setException(exception_wrapper ew) { ...@@ -121,7 +121,7 @@ void Promise<T>::setException(exception_wrapper ew) {
template <class T> template <class T>
template <typename F> template <typename F>
void Promise<T>::setInterruptHandler(F&& fn) { void Promise<T>::setInterruptHandler(F&& fn) {
getCore().setInterruptHandler(std::forward<F>(fn)); getCore().setInterruptHandler(static_cast<F&&>(fn));
} }
template <class T> template <class T>
...@@ -141,14 +141,14 @@ template <class M> ...@@ -141,14 +141,14 @@ template <class M>
void Promise<T>::setValue(M&& v) { void Promise<T>::setValue(M&& v) {
static_assert(!std::is_same<T, void>::value, "Use setValue() instead"); static_assert(!std::is_same<T, void>::value, "Use setValue() instead");
setTry(Try<T>(std::forward<M>(v))); setTry(Try<T>(static_cast<M&&>(v)));
} }
template <class T> template <class T>
template <class F> template <class F>
void Promise<T>::setWith(F&& func) { void Promise<T>::setWith(F&& func) {
throwIfFulfilled(); throwIfFulfilled();
setTry(makeTryWith(std::forward<F>(func))); setTry(makeTryWith(static_cast<F&&>(func)));
} }
template <class T> template <class T>
......
...@@ -96,8 +96,8 @@ void retryingImpl(size_t k, Policy&& p, FF&& ff, Prom prom) { ...@@ -96,8 +96,8 @@ void retryingImpl(size_t k, Policy&& p, FF&& ff, Prom prom) {
auto f = makeFutureWith([&] { return ff(k++); }); auto f = makeFutureWith([&] { return ff(k++); });
std::move(f).thenTry([k, std::move(f).thenTry([k,
prom = std::move(prom), prom = std::move(prom),
pm = std::forward<Policy>(p), pm = static_cast<Policy&&>(p),
ffm = std::forward<FF>(ff)](Try<T>&& t) mutable { ffm = static_cast<FF&&>(ff)](Try<T>&& t) mutable {
if (t.hasValue()) { if (t.hasValue()) {
prom.setValue(std::move(t).value()); prom.setValue(std::move(t).value());
return; return;
...@@ -131,7 +131,7 @@ retrying(size_t k, Policy&& p, FF&& ff) { ...@@ -131,7 +131,7 @@ retrying(size_t k, Policy&& p, FF&& ff) {
auto prom = Promise<T>(); auto prom = Promise<T>();
auto f = prom.getFuture(); auto f = prom.getFuture();
retryingImpl( retryingImpl(
k, std::forward<Policy>(p), std::forward<FF>(ff), std::move(prom)); k, static_cast<Policy&&>(p), static_cast<FF&&>(ff), std::move(prom));
return f; return f;
} }
...@@ -143,13 +143,13 @@ typename std::enable_if< ...@@ -143,13 +143,13 @@ typename std::enable_if<
invoke_result_t<FF, size_t>>::Inner>>::type invoke_result_t<FF, size_t>>::Inner>>::type
retrying(size_t k, Policy&& p, FF&& ff) { retrying(size_t k, Policy&& p, FF&& ff) {
auto sf = folly::makeSemiFuture().deferExValue( auto sf = folly::makeSemiFuture().deferExValue(
[k, p = std::forward<Policy>(p), ff = std::forward<FF>(ff)]( [k, p = static_cast<Policy&&>(p), ff = static_cast<FF&&>(ff)](
Executor::KeepAlive<> ka, auto&&) mutable { Executor::KeepAlive<> ka, auto&&) mutable {
auto futureP = [p = std::forward<Policy>(p), ka]( auto futureP = [p = static_cast<Policy&&>(p), ka](
size_t kk, exception_wrapper e) { size_t kk, exception_wrapper e) {
return p(kk, std::move(e)).via(ka); return p(kk, std::move(e)).via(ka);
}; };
auto futureFF = [ff = std::forward<FF>(ff), ka = std::move(ka)]( auto futureFF = [ff = static_cast<FF&&>(ff), ka = std::move(ka)](
size_t v) { return ff(v).via(ka); }; size_t v) { return ff(v).via(ka); };
return retrying(k, std::move(futureP), std::move(futureFF)); return retrying(k, std::move(futureP), std::move(futureFF));
}); });
...@@ -159,15 +159,15 @@ retrying(size_t k, Policy&& p, FF&& ff) { ...@@ -159,15 +159,15 @@ retrying(size_t k, Policy&& p, FF&& ff) {
template <class Policy, class FF> template <class Policy, class FF>
invoke_result_t<FF, size_t> invoke_result_t<FF, size_t>
retrying(Policy&& p, FF&& ff, retrying_policy_raw_tag) { retrying(Policy&& p, FF&& ff, retrying_policy_raw_tag) {
auto q = [pm = std::forward<Policy>(p)](size_t k, exception_wrapper x) { auto q = [pm = static_cast<Policy&&>(p)](size_t k, exception_wrapper x) {
return makeFuture<bool>(pm(k, x)); return makeFuture<bool>(pm(k, x));
}; };
return retrying(0, std::move(q), std::forward<FF>(ff)); return retrying(0, std::move(q), static_cast<FF&&>(ff));
} }
template <class Policy, class FF> template <class Policy, class FF>
auto retrying(Policy&& p, FF&& ff, retrying_policy_fut_tag) { auto retrying(Policy&& p, FF&& ff, retrying_policy_fut_tag) {
return retrying(0, std::forward<Policy>(p), std::forward<FF>(ff)); return retrying(0, static_cast<Policy&&>(p), static_cast<FF&&>(ff));
} }
// jittered exponential backoff, clamped to [backoff_min, backoff_max] // jittered exponential backoff, clamped to [backoff_min, backoff_max]
...@@ -197,12 +197,12 @@ retryingPolicyCappedJitteredExponentialBackoff( ...@@ -197,12 +197,12 @@ retryingPolicyCappedJitteredExponentialBackoff(
double jitter_param, double jitter_param,
URNG&& rng, URNG&& rng,
Policy&& p) { Policy&& p) {
return [pm = std::forward<Policy>(p), return [pm = static_cast<Policy&&>(p),
max_tries, max_tries,
backoff_min, backoff_min,
backoff_max, backoff_max,
jitter_param, jitter_param,
rngp = std::forward<URNG>(rng)]( rngp = static_cast<URNG&&>(rng)](
size_t n, const exception_wrapper& ex) mutable { size_t n, const exception_wrapper& ex) mutable {
if (n == max_tries) { if (n == max_tries) {
return makeFuture(false); return makeFuture(false);
...@@ -231,7 +231,7 @@ retryingPolicyCappedJitteredExponentialBackoff( ...@@ -231,7 +231,7 @@ retryingPolicyCappedJitteredExponentialBackoff(
URNG&& rng, URNG&& rng,
Policy&& p, Policy&& p,
retrying_policy_raw_tag) { retrying_policy_raw_tag) {
auto q = [pm = std::forward<Policy>(p)]( auto q = [pm = static_cast<Policy&&>(p)](
size_t n, const exception_wrapper& e) { size_t n, const exception_wrapper& e) {
return makeFuture(pm(n, e)); return makeFuture(pm(n, e));
}; };
...@@ -240,7 +240,7 @@ retryingPolicyCappedJitteredExponentialBackoff( ...@@ -240,7 +240,7 @@ retryingPolicyCappedJitteredExponentialBackoff(
backoff_min, backoff_min,
backoff_max, backoff_max,
jitter_param, jitter_param,
std::forward<URNG>(rng), static_cast<URNG&&>(rng),
std::move(q)); std::move(q));
} }
...@@ -259,8 +259,8 @@ retryingPolicyCappedJitteredExponentialBackoff( ...@@ -259,8 +259,8 @@ retryingPolicyCappedJitteredExponentialBackoff(
backoff_min, backoff_min,
backoff_max, backoff_max,
jitter_param, jitter_param,
std::forward<URNG>(rng), static_cast<URNG&&>(rng),
std::forward<Policy>(p)); static_cast<Policy&&>(p));
} }
} // namespace detail } // namespace detail
...@@ -268,7 +268,8 @@ retryingPolicyCappedJitteredExponentialBackoff( ...@@ -268,7 +268,8 @@ retryingPolicyCappedJitteredExponentialBackoff(
template <class Policy, class FF> template <class Policy, class FF>
auto retrying(Policy&& p, FF&& ff) { auto retrying(Policy&& p, FF&& ff) {
using tag = typename detail::retrying_policy_traits<Policy>::tag; using tag = typename detail::retrying_policy_traits<Policy>::tag;
return detail::retrying(std::forward<Policy>(p), std::forward<FF>(ff), tag()); return detail::retrying(
static_cast<Policy&&>(p), static_cast<FF&&>(ff), tag());
} }
inline std::function<bool(size_t, const exception_wrapper&)> inline std::function<bool(size_t, const exception_wrapper&)>
...@@ -291,8 +292,8 @@ retryingPolicyCappedJitteredExponentialBackoff( ...@@ -291,8 +292,8 @@ retryingPolicyCappedJitteredExponentialBackoff(
backoff_min, backoff_min,
backoff_max, backoff_max,
jitter_param, jitter_param,
std::forward<URNG>(rng), static_cast<URNG&&>(rng),
std::forward<Policy>(p), static_cast<Policy&&>(p),
tag()); tag());
} }
......
...@@ -72,13 +72,13 @@ void SharedPromise<T>::setInterruptHandler( ...@@ -72,13 +72,13 @@ void SharedPromise<T>::setInterruptHandler(
template <class T> template <class T>
template <class M> template <class M>
void SharedPromise<T>::setValue(M&& v) { void SharedPromise<T>::setValue(M&& v) {
setTry(Try<T>(std::forward<M>(v))); setTry(Try<T>(static_cast<M&&>(v)));
} }
template <class T> template <class T>
template <class F> template <class F>
void SharedPromise<T>::setWith(F&& func) { void SharedPromise<T>::setWith(F&& func) {
setTry(makeTryWith(std::forward<F>(func))); setTry(makeTryWith(static_cast<F&&>(func)));
} }
template <class T> template <class T>
......
...@@ -445,7 +445,7 @@ class CoreBase { ...@@ -445,7 +445,7 @@ class CoreBase {
} else { } else {
auto oldInterruptHandler = interruptHandler_.exchange( auto oldInterruptHandler = interruptHandler_.exchange(
new InterruptHandlerImpl<typename std::decay<F>::type>( new InterruptHandlerImpl<typename std::decay<F>::type>(
std::forward<F>(fn)), static_cast<F&&>(fn)),
std::memory_order_relaxed); std::memory_order_relaxed);
if (oldInterruptHandler) { if (oldInterruptHandler) {
oldInterruptHandler->release(); oldInterruptHandler->release();
...@@ -530,7 +530,7 @@ class Core final : private ResultHolder<T>, public CoreBase { ...@@ -530,7 +530,7 @@ class Core final : private ResultHolder<T>, public CoreBase {
/// Result held will be the `T` constructed from forwarded `args` /// Result held will be the `T` constructed from forwarded `args`
template <typename... Args> template <typename... Args>
static Core<T>* make(in_place_t, Args&&... args) { static Core<T>* make(in_place_t, Args&&... args) {
return new Core<T>(in_place, std::forward<Args>(args)...); return new Core<T>(in_place, static_cast<Args&&>(args)...);
} }
/// Call only from consumer thread (since the consumer thread can modify the /// Call only from consumer thread (since the consumer thread can modify the
...@@ -582,7 +582,7 @@ class Core final : private ResultHolder<T>, public CoreBase { ...@@ -582,7 +582,7 @@ class Core final : private ResultHolder<T>, public CoreBase {
F&& func, F&& func,
std::shared_ptr<folly::RequestContext>&& context, std::shared_ptr<folly::RequestContext>&& context,
futures::detail::InlineContinuation allowInline) { futures::detail::InlineContinuation allowInline) {
Callback callback = [func = std::forward<F>(func)]( Callback callback = [func = static_cast<F&&>(func)](
CoreBase& coreBase, CoreBase& coreBase,
Executor::KeepAlive<>&& ka, Executor::KeepAlive<>&& ka,
exception_wrapper* ew) mutable { exception_wrapper* ew) mutable {
...@@ -645,7 +645,7 @@ class Core final : private ResultHolder<T>, public CoreBase { ...@@ -645,7 +645,7 @@ class Core final : private ResultHolder<T>, public CoreBase {
explicit Core(in_place_t, Args&&... args) noexcept( explicit Core(in_place_t, Args&&... args) noexcept(
std::is_nothrow_constructible<T, Args&&...>::value) std::is_nothrow_constructible<T, Args&&...>::value)
: CoreBase(State::OnlyResult, 1) { : CoreBase(State::OnlyResult, 1) {
new (&this->result_) Result(in_place, std::forward<Args>(args)...); new (&this->result_) Result(in_place, static_cast<Args&&>(args)...);
} }
~Core() override { ~Core() override {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment