diff options
| author | levlam <levlam@telegram.org> | 2022-06-26 22:31:28 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2022-06-26 22:31:28 +0300 |
| commit | 4b9990aff9bda8f36201872c8a64d18da616ddec (patch) | |
| tree | 06177db8cffea6affe5df69d2230414592b25903 /tdactor | |
| parent | f62632fcbc9d2ac753fd355bafefd812867fe2ee (diff) | |
Simplify LambdaPromise implementation.
Diffstat (limited to 'tdactor')
| -rw-r--r-- | tdactor/td/actor/PromiseFuture.h | 71 |
1 files changed, 22 insertions, 49 deletions
diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index e03738cc2..157381311 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -12,6 +12,7 @@ #include "td/utils/Closure.h" #include "td/utils/common.h" #include "td/utils/invoke.h" +#include "td/utils/logging.h" #include "td/utils/MovableValue.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Status.h" @@ -104,76 +105,48 @@ struct Ignore { } }; -template <class ValueT, class FunctionOkT, class FunctionFailT = Ignore> +template <class ValueT, class FunctionT> class LambdaPromise : public PromiseInterface<ValueT> { - enum class OnFail { None, Ok, Fail }; + enum class State : int32 { Empty, Ready, Complete }; public: void set_value(ValueT &&value) override { - CHECK(has_lambda_.get()); - do_ok(ok_, std::move(value)); - on_fail_ = OnFail::None; + CHECK(state_.get() == State::Ready); + func_(std::move(value)); + state_ = State::Complete; } + void set_error(Status &&error) override { - CHECK(has_lambda_.get()); - do_error(std::move(error)); + if (state_.get() == State::Ready) { + do_error(std::move(error)); + state_ = State::Complete; + } } LambdaPromise(const LambdaPromise &other) = delete; LambdaPromise &operator=(const LambdaPromise &other) = delete; LambdaPromise(LambdaPromise &&other) = default; LambdaPromise &operator=(LambdaPromise &&other) = default; ~LambdaPromise() override { - if (has_lambda_.get()) { + if (state_.get() == State::Ready) { do_error(Status::Error("Lost promise")); } } - template <class FromOkT, class FromFailT> - LambdaPromise(FromOkT &&ok, FromFailT &&fail, bool use_ok_as_fail) - : ok_(std::forward<FromOkT>(ok)) - , fail_(std::forward<FromFailT>(fail)) - , on_fail_(use_ok_as_fail ? OnFail::Ok : OnFail::Fail) - , has_lambda_(true) { - } - template <class FromOkT, std::enable_if_t<!std::is_same<std::decay_t<FromOkT>, LambdaPromise>::value, int> = 0> - LambdaPromise(FromOkT &&ok) : LambdaPromise(std::forward<FromOkT>(ok), Ignore(), true) { + template <class FromT> + explicit LambdaPromise(FromT &&func) : func_(std::forward<FromT>(func)), state_(State::Ready) { } private: - FunctionOkT ok_; - FunctionFailT fail_; - OnFail on_fail_ = OnFail::None; - MovableValue<bool> has_lambda_{false}; - - void do_error(Status &&error) { - switch (on_fail_) { - case OnFail::None: - break; - case OnFail::Ok: - do_error(ok_, std::move(error)); - break; - case OnFail::Fail: - do_error(fail_, std::move(error)); - break; - } - on_fail_ = OnFail::None; - } + FunctionT func_; + MovableValue<State> state_{State::Empty}; - template <class F> - std::enable_if_t<is_callable<F, Result<ValueT>>::value, void> do_error(F &&f, Status &&status) { - f(Result<ValueT>(std::move(status))); - } - template <class Y, class F> - std::enable_if_t<!is_callable<F, Result<ValueT>>::value, void> do_error(F &&f, Y &&status) { - f(Auto()); - } - template <class F> - std::enable_if_t<is_callable<F, Result<ValueT>>::value, void> do_ok(F &&f, ValueT &&result) { - f(Result<ValueT>(std::move(result))); + template <class F = FunctionT> + std::enable_if_t<is_callable<F, Result<ValueT>>::value, void> do_error(Status &&status) { + func_(Result<ValueT>(std::move(status))); } - template <class F> - std::enable_if_t<!is_callable<F, Result<ValueT>>::value, void> do_ok(F &&f, ValueT &&result) { - f(std::move(result)); + template <class Y, class F = FunctionT> + std::enable_if_t<!is_callable<F, Result<ValueT>>::value, void> do_error(Y &&status) { + func_(Auto()); } }; } // namespace detail |
