22#include <dispenso/detail/future_impl.h>
23#include <dispenso/detail/result_of.h>
36constexpr std::launch
kNotAsync =
static_cast<std::launch
>(0);
69template <
typename Result>
70class Future : detail::FutureBase<Result> {
71 using Base = detail::FutureBase<Result>;
86 Future(Base&& f) noexcept : Base(std::move(f)) {}
96 Future(
const Base& f) noexcept : Base(f) {}
112 template <
typename F,
typename Schedulable>
115 Schedulable& schedulable,
116 std::launch asyncPolicy = kNotAsync,
117 std::launch deferredPolicy = std::launch::deferred)
118 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
126 Base::move(
reinterpret_cast<Base&&
>(f));
134 Future& operator=(
const Future& f) {
154 return Base::valid();
165 return Base::is_ready();
188 template <
class Rep,
class Period>
189 std::future_status
wait_for(
const std::chrono::duration<Rep, Period>& timeoutDuration)
const {
190 return Base::wait_for(timeoutDuration);
203 template <
class Clock,
class Duration>
204 std::future_status
wait_until(
const std::chrono::time_point<Clock, Duration>& timeoutTime)
const {
205 return Base::wait_until(timeoutTime);
213 return std::move(*
this);
221 const Result&
get()
const {
223 return this->impl_->result();
241 template <
typename F,
typename Schedulable>
245 std::launch asyncPolicy = kNotAsync,
246 std::launch deferredPolicy = std::launch::deferred) {
248 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<Result>&&>>(
249 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
252 template <
typename F>
253 Future<detail::ResultOf<F, Future<Result>&&>> then(F&& f) {
254 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
258 template <
typename T>
259 Future(T&& t, detail::ReadyTag) {
260 this->impl_ = detail::createValueFutureImplReady<Result>(std::forward<T>(t));
263 template <
typename T>
266 template <
typename R>
273template <
typename Result>
274class Future<Result&> : detail::FutureBase<Result&> {
275 using Base = detail::FutureBase<Result&>;
283 Future(Base&& f) noexcept : Base(std::move(f)) {}
287 Future(
const Base& f) noexcept : Base(f) {}
290 template <
typename F,
typename Schedulable>
293 Schedulable& schedulable,
294 std::launch asyncPolicy = kNotAsync,
295 std::launch deferredPolicy = std::launch::deferred)
296 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
298 Base::move(
reinterpret_cast<Base&&
>(f));
301 Future& operator=(
const Future& f) {
306 using Base::is_ready;
309 using Base::wait_for;
310 using Base::wait_until;
313 return std::move(*
this);
323 return this->impl_->result();
326 template <
typename F,
typename Schedulable>
330 std::launch asyncPolicy = kNotAsync,
331 std::launch deferredPolicy = std::launch::deferred) {
333 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<Result&>&&>>(
334 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
337 template <
typename F>
338 Future<detail::ResultOf<F, Future<Result&>&&>> then(F&& f) {
339 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
343 template <
typename T>
344 Future(std::reference_wrapper<T> t, detail::ReadyTag) {
345 this->impl_ = detail::createRefFutureImplReady<Result>(t);
348 template <
typename X>
351 template <
typename R>
359class Future<void> : detail::FutureBase<void> {
360 using Base = detail::FutureBase<void>;
368 Future(Base&& f) noexcept : Base(std::move(f)) {}
372 Future(
const Base& f) noexcept : Base(f) {}
375 template <
typename F,
typename Schedulable>
376 DISPENSO_REQUIRES(OnceCallableFunc<F>)
379 Schedulable& schedulable,
380 std::launch asyncPolicy = kNotAsync,
381 std::launch deferredPolicy = std::launch::deferred)
382 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
384 Base::move(
reinterpret_cast<Base&&
>(f));
387 Future& operator=(
const Future& f) {
392 using Base::is_ready;
395 using Base::wait_for;
396 using Base::wait_until;
399 return std::move(*
this);
407 this->impl_->result();
410 template <
typename F,
typename Schedulable>
414 std::launch asyncPolicy = kNotAsync,
415 std::launch deferredPolicy = std::launch::deferred) {
417 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<void>&&>>(
418 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
421 template <
typename F>
422 Future<detail::ResultOf<F, Future<void>&&>> then(F&& f) {
423 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
427 Future(detail::ReadyTag) {
428 impl_ = detail::createVoidFutureImplReady();
433 template <
typename R>
452template <
class F,
class... Args>
453inline Future<detail::ResultOf<F, Args...>>
async(std::launch policy, F&& f, Args&&... args) {
454 return Future<detail::ResultOf<F, Args...>>(
455 std::bind(std::forward<F>(f), std::forward<Args>(args)...),
globalThreadPool(), policy);
464template <
class F,
class... Args>
465inline Future<detail::ResultOf<F, Args...>>
async(F&& f, Args&&... args) {
466 return ::dispenso::async(std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
480template <
class F,
class... Args>
481inline Future<detail::ResultOf<F, Args...>>
483 return Future<detail::ResultOf<F, Args...>>(
484 std::bind(std::forward<F>(f), std::forward<Args>(args)...), pool, policy);
494template <
class F,
class... Args>
496 return ::dispenso::async(
497 pool, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
511template <
class F,
class... Args>
512inline Future<detail::ResultOf<F, Args...>>
514 return Future<detail::ResultOf<F, Args...>>(
515 std::bind(std::forward<F>(f), std::forward<Args>(args)...), tasks, policy);
525template <
class F,
class... Args>
527 return ::dispenso::async(
528 tasks, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
542template <
class F,
class... Args>
543inline Future<detail::ResultOf<F, Args...>>
545 return Future<detail::ResultOf<F, Args...>>(
546 std::bind(std::forward<F>(f), std::forward<Args>(args)...), tasks, policy);
556template <
class F,
class... Args>
558 return ::dispenso::async(
559 tasks, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
573template <
class F,
class... Args>
574inline Future<detail::ResultOf<F, Args...>>
576 return Future<detail::ResultOf<F, Args...>>(
577 std::bind(std::forward<F>(f), std::forward<Args>(args)...), sched, policy);
587template <
class F,
class... Args>
589 return ::dispenso::async(
590 sched, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
634template <
class InputIt>
649template <
class... Futures>
665template <
class InputIt>
669template <
class InputIt>
685template <
class... Futures>
690template <
class... Futures>
695#include <dispenso/detail/future_impl2.h>
Future(const Base &f) noexcept
Future(Base &&f) noexcept
Future(const Future &f) noexcept
Future(Future &&f) noexcept
Future(F &&f, Schedulable &schedulable, std::launch asyncPolicy=kNotAsync, std::launch deferredPolicy=std::launch::deferred)
Future(const Base &f) noexcept
Future(const Future &f) noexcept
Future(Future &&f) noexcept
Future(Base &&f) noexcept
Future(Base &&f) noexcept
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(const Base &f) noexcept
Future(Future &&f) noexcept
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
DISPENSO_DLL_ACCESS ThreadPool & globalThreadPool()