21#include <dispenso/detail/future_impl.h>
22#include <dispenso/detail/result_of.h>
35constexpr std::launch
kNotAsync =
static_cast<std::launch
>(0);
68template <
typename Result>
69class Future : detail::FutureBase<Result> {
70 using Base = detail::FutureBase<Result>;
84 Future(Base&& f) noexcept : Base(std::move(f)) {}
93 Future(
const Base& f) noexcept : Base(f) {}
109 template <
typename F,
typename Schedulable>
112 Schedulable& schedulable,
113 std::launch asyncPolicy = kNotAsync,
114 std::launch deferredPolicy = std::launch::deferred)
115 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
123 Base::move(
reinterpret_cast<Base&&
>(f));
151 return Base::valid();
162 return Base::is_ready();
185 template <
class Rep,
class Period>
186 std::future_status
wait_for(
const std::chrono::duration<Rep, Period>& timeoutDuration)
const {
187 return Base::wait_for(timeoutDuration);
200 template <
class Clock,
class Duration>
201 std::future_status
wait_until(
const std::chrono::time_point<Clock, Duration>& timeoutTime)
const {
202 return Base::wait_until(timeoutTime);
210 return std::move(*
this);
218 const Result&
get()
const {
220 return this->impl_->result();
238 template <
typename F,
typename Schedulable>
242 std::launch asyncPolicy = kNotAsync,
243 std::launch deferredPolicy = std::launch::deferred) {
245 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<Result>&&>>(
246 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
249 template <
typename F>
251 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
255 template <
typename T>
256 Future(T&& t, detail::ReadyTag) {
257 this->impl_ = detail::createValueFutureImplReady<Result>(std::forward<T>(t));
260 template <
typename T>
263 template <
typename R>
267template <
typename Result>
268class Future<Result&> : detail::FutureBase<Result&> {
269 using Base = detail::FutureBase<Result&>;
272 Future() noexcept : Base() {}
274 Future(Base&& f) noexcept : Base(std::move(f)) {}
276 Future(
const Base& f) noexcept : Base(f) {}
277 template <
typename F,
typename Schedulable>
280 Schedulable& schedulable,
282 std::launch deferredPolicy = std::launch::deferred)
283 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
285 Base::move(
reinterpret_cast<Base&&
>(f));
293 using Base::is_ready;
296 using Base::wait_for;
297 using Base::wait_until;
300 return std::move(*
this);
310 return this->impl_->result();
313 template <
typename F,
typename Schedulable>
317 std::launch asyncPolicy = kNotAsync,
318 std::launch deferredPolicy = std::launch::deferred) {
320 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<Result&>&&>>(
321 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
324 template <
typename F>
325 Future<detail::ResultOf<F, Future<Result&>&&>> then(F&& f) {
326 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
330 template <
typename T>
331 Future(std::reference_wrapper<T> t, detail::ReadyTag) {
332 this->impl_ = detail::createRefFutureImplReady<Result>(t);
335 template <
typename X>
338 template <
typename R>
343class Future<void> : detail::FutureBase<void> {
344 using Base = detail::FutureBase<void>;
347 Future() noexcept : Base() {}
349 Future(Base&& f) noexcept : Base(std::move(f)) {}
351 Future(
const Base& f) noexcept : Base(f) {}
352 template <
typename F,
typename Schedulable>
355 Schedulable& schedulable,
357 std::launch deferredPolicy = std::launch::deferred)
358 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
360 Base::move(
reinterpret_cast<Base&&
>(f));
368 using Base::is_ready;
371 using Base::wait_for;
372 using Base::wait_until;
375 return std::move(*
this);
383 this->impl_->result();
386 template <
typename F,
typename Schedulable>
390 std::launch asyncPolicy = kNotAsync,
391 std::launch deferredPolicy = std::launch::deferred) {
393 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<void>&&>>(
394 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
397 template <
typename F>
398 Future<detail::ResultOf<F, Future<void>&&>>
then(F&& f) {
399 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
403 Future(detail::ReadyTag) {
404 impl_ = detail::createVoidFutureImplReady();
409 template <
typename R>
428template <
class F,
class... Args>
429inline Future<detail::ResultOf<F, Args...>>
async(std::launch policy, F&& f, Args&&... args) {
430 return Future<detail::ResultOf<F, Args...>>(
431 std::bind(std::forward<F>(f), std::forward<Args>(args)...), globalThreadPool(), policy);
440template <
class F,
class... Args>
441inline Future<detail::ResultOf<F, Args...>>
async(F&& f, Args&&... args) {
442 return ::dispenso::async(std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
456template <
class F,
class... Args>
457inline Future<detail::ResultOf<F, Args...>>
459 return Future<detail::ResultOf<F, Args...>>(
460 std::bind(std::forward<F>(f), std::forward<Args>(args)...), pool, policy);
470template <
class F,
class... Args>
472 return ::dispenso::async(
473 pool, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
487template <
class F,
class... Args>
488inline Future<detail::ResultOf<F, Args...>>
490 return Future<detail::ResultOf<F, Args...>>(
491 std::bind(std::forward<F>(f), std::forward<Args>(args)...), tasks, policy);
501template <
class F,
class... Args>
503 return ::dispenso::async(
504 tasks, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
518template <
class F,
class... Args>
519inline Future<detail::ResultOf<F, Args...>>
521 return Future<detail::ResultOf<F, Args...>>(
522 std::bind(std::forward<F>(f), std::forward<Args>(args)...), tasks, policy);
532template <
class F,
class... Args>
534 return ::dispenso::async(
535 tasks, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
549template <
class F,
class... Args>
550inline Future<detail::ResultOf<F, Args...>>
552 return Future<detail::ResultOf<F, Args...>>(
553 std::bind(std::forward<F>(f), std::forward<Args>(args)...), sched, policy);
563template <
class F,
class... Args>
565 return ::dispenso::async(
566 sched, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
610template <
class InputIt>
625template <
class... Futures>
641template <
class InputIt>
644template <
class InputIt>
660template <
class... Futures>
664template <
class... Futures>
669#include <dispenso/detail/future_impl2.h>
std::future_status wait_until(const std::chrono::time_point< Clock, Duration > &timeoutTime) const
friend Future< std::decay_t< T > > make_ready_future(T &&t)
std::future_status wait_for(const std::chrono::duration< Rep, Period > &timeoutDuration) const
const Result & get() const
Future(const Future &f) noexcept
Future< detail::ResultOf< F, Future< Result > && > > then(F &&f, Schedulable &sched, std::launch asyncPolicy=kNotAsync, std::launch deferredPolicy=std::launch::deferred)
Future & operator=(Future &&f) noexcept
Future(Future &&f) noexcept
Future & operator=(const Future &f)
bool valid() const noexcept
Future(F &&f, Schedulable &schedulable, std::launch asyncPolicy=kNotAsync, std::launch deferredPolicy=std::launch::deferred)
Future< detail::ResultOf< F, Args... > > async(std::launch policy, F &&f, Args &&... args)
Future< std::decay_t< T > > make_ready_future(T &&t)
Future< std::vector< typename std::iterator_traits< InputIt >::value_type > > when_all(InputIt first, InputIt last)
constexpr std::launch kNotAsync
constexpr std::launch kNotDeferred