22 #include <type_traits> 38 #if FOLLY_HAS_COROUTINES 40 #include <experimental/coroutine> 54 using std::logic_error::logic_error;
128 typename =
typename std::enable_if<
131 FutureBase(
T2&&
val);
140 template <
class T2 = T>
146 typename std::enable_if<std::is_constructible<
T,
Args&&...>
::value,
int>
:: 150 FutureBase(FutureBase<T>
const&) =
delete;
163 return core_ !=
nullptr;
185 T
const&
value()
const&;
187 T
const&&
value()
const&&;
206 Try<T> const& result()
const&;
208 Try<T> const&& result()
const&&;
215 bool isReady()
const;
226 bool hasValue()
const;
237 bool hasException()
const;
260 void setCallback_(F&& func);
263 void setCallback_(F&& func, std::shared_ptr<folly::RequestContext>
context);
336 void raise(
E&& exception) {
338 std::forward<E>(exception)));
349 return getCore().getPriority();
367 return getCoreImpl(*
this);
370 return getCoreImpl(*
this);
373 template <
typename Self>
374 static decltype(
auto) getCoreImpl(Self& self) {
376 throw_exception<FutureInvalid>();
382 return getCoreTryChecked(*
this);
385 return getCoreTryChecked(*
this);
388 template <
typename Self>
389 static decltype(
auto) getCoreTryChecked(Self& self) {
390 auto& core =
self.getCore();
391 if (!core.hasResult()) {
392 throw_exception<FutureNotReady>();
394 return core.getTry();
407 void throwIfInvalid()
const;
408 void throwIfContinued()
const;
413 return getCore().getExecutor();
421 getCore().setExecutor(x, priority);
427 getCore().setExecutor(
std::move(x), priority);
432 template <
typename F,
typename R>
434 thenImplementation(F&& func, R);
438 template <
typename F,
typename R>
440 thenImplementation(F&& func, R);
442 template <
typename E>
450 template <
typename T>
453 template <
typename T>
492 using TimePoint = std::chrono::system_clock::time_point;
518 typename =
typename std::enable_if<
530 template <
class T2 = T>
546 typename std::enable_if<std::is_constructible<
T,
Args&&...>
::value,
int>
:: 558 using Base::getPriority;
559 using Base::hasException;
560 using Base::hasValue;
565 using Base::setCallback_;
586 [[deprecated(
"must be rvalue-qualified, e.g., std::move(future).get()")]] T
602 [[deprecated(
"must be rvalue-qualified, e.g., std::move(future).get(dur)")]] T
696 template <
typename F>
700 template <
typename R,
typename...
Args>
715 template <
typename F>
717 deferValue(F&& func) &&;
719 template <
typename R,
typename...
Args>
721 return std::move(*this).deferValue(&func);
750 template <
class ExceptionType,
class F>
753 template <
class ExceptionType,
class R,
class...
Args>
755 return std::move(*this).template deferError<ExceptionType>(&func);
785 template <
class R,
class...
Args>
787 return std::move(*this).deferError(&func);
796 return this->isReady() ?
std::move(*
this)
797 :
std::move(*this).withinImplementation(dur, e, tk);
831 #if FOLLY_HAS_COROUTINES 838 std::experimental::suspend_never initial_suspend() {
842 std::experimental::suspend_never final_suspend() {
846 void return_value(
const T&
value) {
850 void return_value(T&& value) {
854 void unhandled_exception() {
856 std::rethrow_exception(std::current_exception());
857 }
catch (std::exception& e) {
887 futures::detail::stealDeferredExecutor<T>(
SemiFuture&);
890 using Base::setExecutor;
891 using Base::throwIfInvalid;
921 static void releaseDeferredExecutor(
Core* core);
927 auto f = p.getSemiFuture();
978 typename =
typename std::enable_if<
990 template <
class T2 = T>
1006 typename std::enable_if<std::is_constructible<
T,
Args&&...>
::value,
int>
:: 1018 typename std::enable_if<
1026 typename std::enable_if<
1029 !std::is_convertible<T2&&, T>::value,
1034 typename std::enable_if<
1041 using Base::getPriority;
1042 using Base::hasException;
1043 using Base::hasValue;
1044 using Base::isReady;
1048 using Base::setCallback_;
1100 template <
class F = T>
1162 template <
typename F,
typename R = futures::detail::callableResult<T, F>>
1163 [[deprecated(
"ERROR: use thenValue instead")]]
typename std::enable_if<
1167 return std::move(*this).thenValue(std::forward<F>(func));
1170 template <
typename F,
typename R = futures::detail::callableResult<T, F>>
1171 [[deprecated(
"ERROR: use thenTry instead")]]
typename std::enable_if<
1175 return std::move(*this).thenTry(std::forward<F>(func));
1178 template <
typename F,
typename R = futures::detail::callableResult<T, F>>
1180 "ERROR: use thenValue with auto&& or folly::Unit parameter instead")]]
1182 then(F&& func) && =
delete;
1185 template <
typename F,
typename R = futures::detail::callableResult<T, F>>
1187 "must be rvalue-qualified, e.g., std::move(future).thenValue(...)")]]
1188 typename R::Return then(F&& func) & =
delete;
1211 template <
typename R,
typename Caller,
typename...
Args>
1213 R (Caller::*func)(
Args...),
1214 Caller* instance) &&;
1217 template <
typename R,
typename Caller,
typename...
Args>
1219 "must be rvalue-qualified, e.g., std::move(future).then(...)")]]
1221 then(R (Caller::*func)(
Args...), Caller* instance) & =
delete;
1246 template <
class Arg>
1249 this->setExecutor(
x);
1256 .thenImplementation(std::forward<Arg>(arg), R{})
1260 template <
class R,
class Caller,
class...
Args>
1263 this->setExecutor(x);
1265 return std::move(*this).then(func, instance).via(oldX);
1268 template <
class Arg,
class...
Args>
1270 "must be rvalue-qualified, e.g., std::move(future).then(...)")]]
auto 1271 then(
Executor* x, Arg&& arg,
Args&&... args) & =
delete;
1294 template <
typename F>
1298 template <
typename R,
typename...
Args>
1324 template <
typename F>
1326 thenValue(F&& func) &&;
1328 template <
typename R,
typename...
Args>
1330 return std::move(*this).thenValue(&func);
1357 template <
class ExceptionType,
class F>
1360 template <
class ExceptionType,
class R,
class...
Args>
1362 return std::move(*this).template thenError<ExceptionType>(&func);
1392 template <
class R,
class...
Args>
1394 return std::move(*this).thenError(&func);
1414 "must be rvalue-qualified, e.g., std::move(future).thenValue()")]]
1462 typename std::enable_if<
1466 onError(F&& func) &&;
1480 typename std::enable_if<
1484 onError(F&& func) &&;
1498 typename std::enable_if<
1500 futures::detail::Extract<F>::ReturnsFuture::value,
1502 onError(F&& func) &&;
1516 typename std::enable_if<
1518 !futures::detail::Extract<F>::ReturnsFuture::value,
1520 onError(F&& func) &&;
1524 [[deprecated(
"use rvalue-qualified fn, eg, std::move(future).onError(...)")]]
1526 return std::move(*this).onError(std::forward<F>(func));
1634 [[deprecated(
"must be rvalue-qualified, e.g., std::move(future).get()")]] T
1650 [[deprecated(
"must be rvalue-qualified, e.g., std::move(future).get(dur)")]] T
1803 template <
class I,
class F>
1824 template <
class Callback,
class... Callbacks>
1833 .thenImplementation(std::forward<Callback>(fn), R{})
1834 .thenMulti(std::forward<Callbacks>(fns)...);
1848 template <
class Callback>
1856 return std::move(*this).thenImplementation(std::forward<Callback>(fn), R{});
1859 template <
class Callback>
1861 return std::move(*this).thenMulti(std::forward<Callback>(fn));
1882 template <
class Callback,
class... Callbacks>
1888 this->setExecutor(x);
1894 .thenImplementation(std::forward<Callback>(fn), R{})
1895 .thenMulti(std::forward<Callbacks>(fns)...)
1899 template <
class Callback>
1902 return std::move(*this).then(x, std::forward<Callback>(fn));
1916 #if FOLLY_HAS_COROUTINES 1939 using Base::setExecutor;
1940 using Base::throwIfContinued;
1941 using Base::throwIfInvalid;
1971 template <
class P,
class F>
2028 template <
class Clock>
2035 auto f = p.getSemiFuture().via(e);
2041 #if FOLLY_HAS_COROUTINES 2046 template <
typename T>
2047 class FutureAwaitable {
2052 bool await_ready()
const {
2060 void await_suspend(std::experimental::coroutine_handle<>
h) {
2061 future_.setCallback_([h](
Try<T>&&)
mutable {
2073 template <
typename T>
2074 inline detail::FutureAwaitable<T>
2075 operator co_await(
Future<T>&& future) noexcept {
2076 return detail::FutureAwaitable<T>(
std::move(future));
2086 template <
typename Awaitable>
2087 inline auto toSemiFuture(Awaitable awaitable) -> std::enable_if_t<
2088 !std::is_void<folly::coro::await_result_t<Awaitable>>
::value,
2090 co_return co_await
static_cast<Awaitable&&
>(awaitable);
2093 template <
typename Awaitable>
2094 inline auto toSemiFuture(Awaitable awaitable) -> std::enable_if_t<
2095 std::is_void<folly::coro::await_result_t<Awaitable>>
::value,
2097 co_await
static_cast<Awaitable&&
>(awaitable);
std::enable_if< !is_invocable< F, T && >::value &&!is_invocable< F >::value, typename R::Return >::type then(F &&func)&&
Future< Unit > whileDo(P &&predicate, F &&thunk)
auto thenMulti(Callback &&fn)&
folly::Executor * getExecutor()
SemiFuture(futures::detail::EmptyConstruct) noexcept
static const int8_t MID_PRI
PUSHMI_INLINE_VAR constexpr detail::filter_fn filter
auto then(Executor *x, R(Caller::*func)(Args...), Caller *instance)&&
auto thenTry(R(&func)(Args...))&&
Future< T > thenError(R(&func)(Args...))&&
Future(typename std::enable_if< std::is_same< Unit, T2 >::value >::type *p=nullptr)
auto deferValue(R(&func)(Args...))&&
auto then(Executor *x, Arg &&arg)&&
Executor * getExecutor() const
constexpr detail::Map< Move > move
auto co_viaIfAsync(folly::Executor *executor, Awaitable &&awaitable) -> ViaIfAsyncAwaitable< Awaitable >
void convertFuture(SemiFuture< T > &&sf, Future< T > &f)
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
Future(in_place_t, Args &&...args)
—— Concurrent Priority Queue Implementation ——
std::chrono::system_clock::time_point TimePoint
SemiFuture(in_place_t, Args &&...args)
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::defer_fn defer
in_place_tag in_place(in_place_tag={})
requires E e noexcept(noexcept(s.error(std::move(e))))
in_place_tag(&)(in_place_tag) in_place_t
auto defer(R(&func)(Args...))&&
auto thenMultiWithExecutor(Executor *x, Callback &&fn, Callbacks &&...fns)&&
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
SemiFuture(typename std::enable_if< std::is_same< Unit, T2 >::value >::type *p=nullptr)
DeferredExecutor * getDeferredExecutor(SemiFuture< T > &future)
Future(futures::detail::EmptyConstruct) noexcept
auto thenMultiWithExecutor(Executor *x, Callback &&fn)&&
auto thenMulti(Callback &&fn)&&
std::chrono::milliseconds Duration
SemiFuture< T > within(Duration dur, E e, Timekeeper *tk=nullptr)&&
SemiFuture< T > deferError(R(&func)(Args...))&&
Try< T > & getCoreTryChecked()
void setExecutor(Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
SemiFuture< T > within(Duration dur, Timekeeper *tk=nullptr)&&
Future< T > reduce(It first, It last, T &&initial, F &&func)
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
auto thenValue(R(&func)(Args...))&&
static const char *const value
Future< Unit > when(bool p, F &&thunk)
auto thenMulti(Callback &&fn, Callbacks &&...fns)&&
void setExecutor(Executor *x, int8_t priority=Executor::MID_PRI)
std::pair< Promise< T >, SemiFuture< T > > makePromiseContract()
Try< T > const & getCoreTryChecked() const
Future< T > onError(F &&func)&
Core const & getCore() const
int poll(PollDescriptor fds[], nfds_t nfds, int timeout)
std::enable_if< !is_invocable< F >::value &&is_invocable< F, T && >::value, typename R::Return >::type then(F &&func)&&
int8_t getPriority() const
constexpr detail::Unwrap unwrap
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
auto via(Executor *x, Func &&func) -> Future< typename isFutureOrSemiFuture< decltype(std::declval< Func >()())>::Inner >
folly::Executor::KeepAlive< DeferredExecutor > stealDeferredExecutor(SemiFuture< T > &future)
FuturePredicateDoesNotObtain()
Future< Unit > times(const int n, F &&thunk)
Future< typename std::decay< T >::type > makeFuture(T &&t)
Future< T > thenError(R(&func)(Args...))&&
SemiFuture< T > deferError(R(&func)(Args...))&&
internal::ReturnAction< R > Return(R value)
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)