/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once // included by Future.h, do not include directly. namespace folly { template class Promise; template class SemiFuture; template struct isSemiFuture : std::false_type { using Inner = lift_unit_t; }; template struct isSemiFuture> : std::true_type { typedef T Inner; }; template struct isFuture : std::false_type { using Inner = lift_unit_t; }; template struct isFuture> : std::true_type { typedef T Inner; }; template struct isFutureOrSemiFuture : std::false_type { using Inner = lift_unit_t; using Return = Inner; }; template struct isFutureOrSemiFuture> : std::false_type { using Inner = lift_unit_t; using Return = Inner; }; template struct isFutureOrSemiFuture> : std::true_type { typedef T Inner; using Return = Future; }; template struct isFutureOrSemiFuture>> : std::true_type { typedef T Inner; using Return = Future; }; template struct isFutureOrSemiFuture> : std::true_type { typedef T Inner; using Return = SemiFuture; }; template struct isFutureOrSemiFuture>> : std::true_type { typedef T Inner; using Return = SemiFuture; }; namespace futures { namespace detail { template class Core; template struct ArgType; template struct ArgType { typedef Arg FirstArg; typedef ArgType Tail; }; template <> struct ArgType<> { typedef void FirstArg; }; template struct argResult { using Function = F; using ArgList = ArgType; using Result = invoke_result_t; using ArgsSize = index_constant; static constexpr bool isTry() { return isTry_; } }; template struct callableResult { typedef typename std::conditional< is_invocable_v, detail::argResult, typename std::conditional< is_invocable_v, detail::argResult, detail::argResult&&>>::type>::type Arg; typedef isFutureOrSemiFuture ReturnsFuture; typedef Future Return; }; template struct executorCallableResult { typedef typename std::conditional< is_invocable_v&&>, detail::argResult&&>, typename std::conditional< is_invocable_v&&, T&&>, detail::argResult&&, T&&>, detail::argResult&&, Try&&>>:: type>::type Arg; typedef isFutureOrSemiFuture ReturnsFuture; typedef Future Return; }; template < typename T, typename F, typename = std::enable_if_t&&>>> struct tryCallableResult { typedef detail::argResult&&> Arg; typedef isFutureOrSemiFuture ReturnsFuture; typedef typename ReturnsFuture::Inner value_type; typedef Future Return; }; template < typename T, typename F, typename = std::enable_if_t&&>>> struct tryExecutorCallableResult { typedef detail::argResult&&, Try&&> Arg; typedef isFutureOrSemiFuture ReturnsFuture; typedef typename ReturnsFuture::Inner value_type; typedef Future Return; }; template struct valueCallableResult { typedef detail::argResult Arg; typedef isFutureOrSemiFuture ReturnsFuture; typedef typename ReturnsFuture::Inner value_type; typedef typename Arg::ArgList::FirstArg FirstArg; typedef Future Return; }; template struct valueExecutorCallableResult { typedef detail::argResult&&, T&&> Arg; typedef isFutureOrSemiFuture ReturnsFuture; typedef typename ReturnsFuture::Inner value_type; typedef typename Arg::ArgList::Tail::FirstArg ValueArg; typedef Future Return; }; template struct Extract : Extract {}; template struct Extract { typedef isFutureOrSemiFuture ReturnsFuture; typedef Future Return; typedef typename ReturnsFuture::Inner RawReturn; typedef typename ArgType::FirstArg FirstArg; }; template struct Extract { typedef isFutureOrSemiFuture ReturnsFuture; typedef Future Return; typedef typename ReturnsFuture::Inner RawReturn; typedef typename ArgType::FirstArg FirstArg; }; template struct Extract { typedef isFutureOrSemiFuture ReturnsFuture; typedef Future Return; typedef typename ReturnsFuture::Inner RawReturn; typedef typename ArgType::FirstArg FirstArg; }; template struct Extract { typedef isFutureOrSemiFuture ReturnsFuture; typedef Future Return; typedef typename ReturnsFuture::Inner RawReturn; typedef typename ArgType::FirstArg FirstArg; }; class DeferredExecutor; template auto makeExecutorLambda( F&& func, typename std::enable_if, int>::type = 0) { return [func = std::forward(func)](Executor::KeepAlive<>&&, auto&&) mutable { return std::forward(func)(); }; } template auto makeExecutorLambda( F&& func, typename std::enable_if, int>::type = 0) { using R = futures::detail::callableResult; return [func = std::forward(func)]( Executor::KeepAlive<>&&, typename R::Arg::ArgList::FirstArg&& param) mutable { return std::forward(func)(std::forward(param)); }; } } // namespace detail } // namespace futures class Timekeeper; } // namespace folly