1#ifndef ORIGINAL_ASYNC_H
2#define ORIGINAL_ASYNC_H
30 template<
typename TYPE>
32 atomic<bool> ready_{makeAtomic(
false)};
36 std::exception_ptr e_{};
45 void setValue(TYPE&& v);
51 void setException(std::exception_ptr e);
57 [[nodiscard]]
bool ready()
const;
74 void rethrowIfException()
const;
80 [[nodiscard]] std::exception_ptr exception()
const;
86 [[nodiscard]]
bool available()
const;
99 template<
typename TYPE>
128 [[nodiscard]]
bool ready()
const;
134 [[nodiscard]] std::exception_ptr
exception()
const noexcept;
151 template<
typename TYPE,
typename Callback>
153 std::function<TYPE()> c_;
187 template <
typename Callback,
typename... Args>
188 static auto makePromise(Callback&& c, Args&&... args);
199 template <
typename Callback,
typename... Args>
200 static auto get(Callback&& c, Args&&... args);
209 class async::asyncWrapper<void> {
210 atomic<bool> ready_{makeAtomic(
false)};
214 std::exception_ptr e_{};
217 asyncWrapper() =
default;
228 void setException(std::exception_ptr e);
234 [[nodiscard]]
bool ready()
const;
250 void rethrowIfException()
const;
256 [[nodiscard]] std::exception_ptr exception()
const noexcept;
262 [[nodiscard]]
bool available()
const;
273 explicit future(
const strongPtr<asyncWrapper<void>>& awr) : awr_(std::move(awr)) {}
296 [[nodiscard]]
bool ready()
const;
302 [[nodiscard]] std::exception_ptr
exception()
const noexcept;
314 template <
typename Callback>
316 std::function<void()> c_;
326 explicit promise(Callback&& c);
341template <
typename TYPE>
342original::async::asyncWrapper<TYPE>::asyncWrapper() =
default;
344template <
typename TYPE>
345void original::async::asyncWrapper<TYPE>::setValue(TYPE&& v)
349 this->alter_.set(std::move(v));
350 this->ready_.store(
true);
352 this->cond_.notify();
355template <
typename TYPE>
356void original::async::asyncWrapper<TYPE>::setException(std::exception_ptr e)
359 uniqueLock lock{this->mutex_};
360 this->e_ = std::move(e);
361 this->ready_.store(
true);
363 this->cond_.notify();
366template <
typename TYPE>
367bool original::async::asyncWrapper<TYPE>::ready()
const
369 return this->ready_.load();
372template <
typename TYPE>
373void original::async::asyncWrapper<TYPE>::wait()
375 uniqueLock lock{this->mutex_};
376 this->cond_.wait(this->mutex_, [
this]
378 return this->ready();
382template <
typename TYPE>
383TYPE original::async::asyncWrapper<TYPE>::get()
385 uniqueLock lock{this->mutex_};
386 this->cond_.wait(this->mutex_, [
this]{
387 return this->ready();
390 if (this->e_) std::rethrow_exception(this->e_);
392 TYPE result = *this->alter_;
393 this->alter_.reset();
397template <
typename TYPE>
398void original::async::asyncWrapper<TYPE>::rethrowIfException()
const
401 std::rethrow_exception(this->e_);
404template <
typename TYPE>
406original::async::asyncWrapper<TYPE>::exception()
const
408 uniqueLock lock{this->mutex_};
412template <
typename TYPE>
413bool original::async::asyncWrapper<TYPE>::available()
const
415 uniqueLock lock{this->mutex_};
416 return this->ready() && this->alter_.hasValue();
419template <
typename TYPE>
423template <
typename TYPE>
426 return this->awr_->get();
429template <
typename TYPE>
432 return this->awr_->ready();
435template <
typename TYPE>
438 return this->awr_->exception();
441template <
typename TYPE>
447template <
typename TYPE,
typename Callback>
449 : c_(std::forward<Callback>(c)), awr_(
makeStrongPtr<asyncWrapper<TYPE>>()) {}
451template <
typename TYPE,
typename Callback>
458template <
typename TYPE,
typename Callback>
462 if constexpr (!std::is_void_v<TYPE>) {
463 this->awr_->setValue(this->c_());
466 this->awr_->setValue({});
469 this->awr_->setException(std::current_exception());
473template <
typename Callback,
typename... Args>
475 using Return = std::invoke_result_t<Callback, Args...>;
476 auto bound = [c = std::forward<Callback>(c),
477 ... args = std::forward<Args>(args)]()
mutable -> Return {
481 return promise<Return,
decltype(bound)>{std::move(bound)};
484template <
typename Callback,
typename ... Args>
487 using ResultType = std::invoke_result_t<std::decay_t<Callback>, std::decay_t<Args>...>;
488 auto task = [c = std::forward<Callback>(c), ... args = std::forward<Args>(args)]()
mutable -> ResultType {
489 return c(std::forward<Args>(args)...);
493 auto fut = p.getFuture();
496 [p = std::move(p)]()
mutable {
504inline void original::async::asyncWrapper<void>::setValue()
509 this->ready_.store(
true);
511 this->cond_.notify();
514inline void original::async::asyncWrapper<void>::setException(std::exception_ptr e)
518 this->e_ = std::move(e);
519 this->ready_.store(
true);
521 this->cond_.notify();
524inline bool original::async::asyncWrapper<void>::ready()
const
526 return this->ready_.load();
529inline void original::async::asyncWrapper<void>::wait()
532 this->cond_.wait(this->mutex_, [
this]
534 return this->ready();
538inline void original::async::asyncWrapper<void>::get()
541 this->cond_.wait(this->mutex_, [
this] {
542 return this->ready();
545 if (this->e_) std::rethrow_exception(this->e_);
548inline void original::async::asyncWrapper<void>::rethrowIfException()
const
551 std::rethrow_exception(this->e_);
554inline std::exception_ptr
555original::async::asyncWrapper<void>::exception() const noexcept
561inline bool original::async::asyncWrapper<void>::available()
const
564 return this->ready() && this->alter_.hasValue();
574 return this->awr_->ready();
579 return this->awr_->exception();
587template <
typename Callback>
589 : c_(std::forward<Callback>(c)), awr_(
makeStrongPtr<asyncWrapper<void>>()) {}
591template <
typename Callback>
597template <
typename Callback>
602 this->awr_->setValue();
604 this->awr_->setException(std::current_exception());
A type-safe container that may or may not contain a value.
Definition optional.h:45
Represents a future result of an asynchronous computation.
Definition async.h:100
bool ready() const
Checks if the result is ready.
Definition async.h:430
std::exception_ptr exception() const noexcept
Gets the exception if computation failed.
Definition async.h:436
TYPE result()
Gets the result (blocks until ready)
Definition async.h:424
void wait()
Waits until the result becomes ready.
Definition async.h:442
Represents a promise of a future result.
Definition async.h:152
promise(Callback &&c)
Constructs a promise with a computation callback.
Definition async.h:448
future< TYPE > getFuture()
Gets the future associated with this promise.
Definition async.h:453
void run()
Executes the computation and sets the result.
Definition async.h:459
Asynchronous programming utilities with future/promise pattern.
Definition async.h:21
static auto get(Callback &&c, Args &&... args)
Executes a callable asynchronously and gets the result.
Definition async.h:485
static auto makePromise(Callback &&c, Args &&... args)
Creates a promise from a callable and arguments.
Definition async.h:474
POSIX condition variable implementation.
Definition condition.h:114
POSIX thread mutex implementation.
Definition mutex.h:153
Shared ownership smart pointer with strong references.
Definition refCntPtr.h:108
Concrete task implementation with result type.
Definition tasks.h:43
High-level thread wrapper.
Definition thread.h:263
RAII wrapper for single mutex locking.
Definition mutex.h:216
Condition variable implementation for thread synchronization.
Main namespace for the project Original.
Definition algorithms.h:21
strongPtr< T, DEL > makeStrongPtr(Args &&... args)
Creates a new strongPtr managing a shared object.
Definition refCntPtr.h:633
Type-safe optional value container.
Reference-counted smart pointer hierarchy.
Thread management utilities.