add nf7::AggregatePromise

This commit is contained in:
falsycat 2022-10-15 08:14:49 +09:00
parent 4e83f7b5e9
commit 94615b3669
3 changed files with 75 additions and 3 deletions

View File

@ -64,6 +64,7 @@ target_sources(nf7
theme.hh
common/aggregate_command.hh
common/aggregate_promise.hh
common/audio_queue.hh
common/dir.hh
common/dir_item.hh

View File

@ -0,0 +1,68 @@
#pragma once
#include <memory>
#include "nf7.hh"
#include "common/future.hh"
namespace nf7 {
class AggregatePromise final :
public std::enable_shared_from_this<AggregatePromise> {
public:
AggregatePromise() = delete;
AggregatePromise(const std::shared_ptr<nf7::Context>& ctx) noexcept :
data_(std::make_shared<Data>(ctx)) {
data_->Ref();
}
~AggregatePromise() noexcept {
data_->Unref();
}
AggregatePromise(const AggregatePromise&) = delete;
AggregatePromise(AggregatePromise&&) = delete;
AggregatePromise& operator=(const AggregatePromise&) = delete;
AggregatePromise& operator=(AggregatePromise&&) = delete;
AggregatePromise& Add(auto& fu) noexcept {
data_->Ref();
fu.Then([data = data_](auto&) { data->Unref(); });
return *this;
}
nf7::Future<std::monostate> future() noexcept {
return data_->future();
}
private:
struct Data {
public:
Data() = delete;
Data(const std::shared_ptr<nf7::Context>& ctx) noexcept :
pro_(ctx) {
}
void Ref() noexcept {
++refcnt_;
}
void Unref() noexcept {
if (0 == --refcnt_) {
pro_.Return({});
}
}
nf7::Future<std::monostate> future() const noexcept {
return pro_.future();
}
private:
nf7::Future<std::monostate>::Promise pro_;
std::atomic<size_t> refcnt_ = 0;
};
std::shared_ptr<Data> data_;
};
} // namespace nf7

View File

@ -324,11 +324,14 @@ class Future final {
return !imm_ && data_->state == kYet;
}
bool done() const noexcept {
return (imm_ && std::holds_alternative<T>(*imm_)) || data_->state == kDone;
return
(imm_ && std::holds_alternative<T>(*imm_)) ||
(data_ && data_->state == kDone);
}
bool error() const noexcept {
return (imm_ && std::holds_alternative<std::exception_ptr>(*imm_)) ||
data_->state == kError;
return
(imm_ && std::holds_alternative<std::exception_ptr>(*imm_)) ||
(data_ && data_->state == kError);
}
bool await_ready() const noexcept { return !yet(); }