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>;
85 Future(Base&& f) noexcept : Base(std::move(f)) {}
94 Future(
const Base& f) noexcept : Base(f) {}
110 template <
typename F,
typename Schedulable>
113 Schedulable& schedulable,
114 std::launch asyncPolicy = kNotAsync,
115 std::launch deferredPolicy = std::launch::deferred)
116 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
124 Base::move(
reinterpret_cast<Base&&
>(f));
152 return Base::valid();
163 return Base::is_ready();
186 template <
class Rep,
class Period>
187 std::future_status
wait_for(
const std::chrono::duration<Rep, Period>& timeoutDuration)
const {
188 return Base::wait_for(timeoutDuration);
201 template <
class Clock,
class Duration>
202 std::future_status
wait_until(
const std::chrono::time_point<Clock, Duration>& timeoutTime)
const {
203 return Base::wait_until(timeoutTime);
211 return std::move(*
this);
219 const Result&
get()
const {
221 return this->impl_->result();
239 template <
typename F,
typename Schedulable>
243 std::launch asyncPolicy = kNotAsync,
244 std::launch deferredPolicy = std::launch::deferred) {
246 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<Result>&&>>(
247 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
250 template <
typename F>
252 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
256 template <
typename T>
257 Future(T&& t, detail::ReadyTag) {
258 this->impl_ = detail::createValueFutureImplReady<Result>(std::forward<T>(t));
261 template <
typename T>
264 template <
typename R>
268template <
typename Result>
269class Future<Result&> : detail::FutureBase<Result&> {
270 using Base = detail::FutureBase<Result&>;
273 Future() noexcept : Base() {}
275 Future(Base&& f) noexcept : Base(std::move(f)) {}
277 Future(
const Base& f) noexcept : Base(f) {}
278 template <
typename F,
typename Schedulable>
281 Schedulable& schedulable,
283 std::launch deferredPolicy = std::launch::deferred)
284 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
286 Base::move(
reinterpret_cast<Base&&
>(f));
294 using Base::is_ready;
297 using Base::wait_for;
298 using Base::wait_until;
301 return std::move(*
this);
311 return this->impl_->result();
314 template <
typename F,
typename Schedulable>
318 std::launch asyncPolicy = kNotAsync,
319 std::launch deferredPolicy = std::launch::deferred) {
321 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<Result&>&&>>(
322 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
325 template <
typename F>
326 Future<detail::ResultOf<F, Future<Result&>&&>> then(F&& f) {
327 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
331 template <
typename T>
332 Future(std::reference_wrapper<T> t, detail::ReadyTag) {
333 this->impl_ = detail::createRefFutureImplReady<Result>(t);
336 template <
typename X>
339 template <
typename R>
344class Future<void> : detail::FutureBase<void> {
345 using Base = detail::FutureBase<void>;
348 Future() noexcept : Base() {}
350 Future(Base&& f) noexcept : Base(std::move(f)) {}
352 Future(
const Base& f) noexcept : Base(f) {}
353 template <
typename F,
typename Schedulable>
356 Schedulable& schedulable,
358 std::launch deferredPolicy = std::launch::deferred)
359 : Base(std::forward<F>(f), schedulable, asyncPolicy, deferredPolicy) {}
361 Base::move(
reinterpret_cast<Base&&
>(f));
369 using Base::is_ready;
372 using Base::wait_for;
373 using Base::wait_until;
376 return std::move(*
this);
384 this->impl_->result();
387 template <
typename F,
typename Schedulable>
391 std::launch asyncPolicy = kNotAsync,
392 std::launch deferredPolicy = std::launch::deferred) {
394 retFuture.impl_ = this->
template thenImpl<detail::ResultOf<F, Future<void>&&>>(
395 std::forward<F>(f), sched, asyncPolicy, deferredPolicy);
398 template <
typename F>
399 Future<detail::ResultOf<F, Future<void>&&>>
then(F&& f) {
400 return then(std::forward<F>(f), globalThreadPool(), kNotAsync, std::launch::deferred);
404 Future(detail::ReadyTag) {
405 impl_ = detail::createVoidFutureImplReady();
410 template <
typename R>
429template <
class F,
class... Args>
430inline Future<detail::ResultOf<F, Args...>>
async(std::launch policy, F&& f, Args&&... args) {
431 return Future<detail::ResultOf<F, Args...>>(
432 std::bind(std::forward<F>(f), std::forward<Args>(args)...), globalThreadPool(), policy);
441template <
class F,
class... Args>
442inline Future<detail::ResultOf<F, Args...>>
async(F&& f, Args&&... args) {
443 return ::dispenso::async(std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
457template <
class F,
class... Args>
458inline Future<detail::ResultOf<F, Args...>>
460 return Future<detail::ResultOf<F, Args...>>(
461 std::bind(std::forward<F>(f), std::forward<Args>(args)...), pool, policy);
471template <
class F,
class... Args>
473 return ::dispenso::async(
474 pool, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
488template <
class F,
class... Args>
489inline Future<detail::ResultOf<F, Args...>>
491 return Future<detail::ResultOf<F, Args...>>(
492 std::bind(std::forward<F>(f), std::forward<Args>(args)...), tasks, policy);
502template <
class F,
class... Args>
504 return ::dispenso::async(
505 tasks, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
519template <
class F,
class... Args>
520inline Future<detail::ResultOf<F, Args...>>
522 return Future<detail::ResultOf<F, Args...>>(
523 std::bind(std::forward<F>(f), std::forward<Args>(args)...), tasks, policy);
533template <
class F,
class... Args>
535 return ::dispenso::async(
536 tasks, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
550template <
class F,
class... Args>
551inline Future<detail::ResultOf<F, Args...>>
553 return Future<detail::ResultOf<F, Args...>>(
554 std::bind(std::forward<F>(f), std::forward<Args>(args)...), sched, policy);
564template <
class F,
class... Args>
566 return ::dispenso::async(
567 sched, std::launch::deferred, std::forward<F>(f), std::forward<Args>(args)...);
611template <
class InputIt>
626template <
class... Futures>
642template <
class InputIt>
645template <
class InputIt>
661template <
class... Futures>
665template <
class... Futures>
670#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