aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/threading/future/core
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-07-29 14:55:30 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-07-29 15:09:48 +0300
commit80adf9ab238b01ed48926dca38bf7eefd39c823d (patch)
tree0565154984fed73dc32aaf76c402f81c54ac46f6 /library/cpp/threading/future/core
parent5d639bd83a0f3642a1c2b605bcac23a25a071920 (diff)
downloadydb-80adf9ab238b01ed48926dca38bf7eefd39c823d.tar.gz
Intermediate changes
Diffstat (limited to 'library/cpp/threading/future/core')
-rw-r--r--library/cpp/threading/future/core/coroutine_traits.h99
1 files changed, 99 insertions, 0 deletions
diff --git a/library/cpp/threading/future/core/coroutine_traits.h b/library/cpp/threading/future/core/coroutine_traits.h
new file mode 100644
index 0000000000..5871e22a35
--- /dev/null
+++ b/library/cpp/threading/future/core/coroutine_traits.h
@@ -0,0 +1,99 @@
+#pragma once
+
+#include <library/cpp/threading/future/future.h>
+
+#include <coroutine>
+
+template<typename... Args>
+struct std::coroutine_traits<NThreading::TFuture<void>, Args...> {
+ struct promise_type {
+
+ NThreading::TFuture<void> get_return_object() {
+ return Promise_.GetFuture();
+ }
+
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+
+ void unhandled_exception() {
+ Promise_.SetException(std::current_exception());
+ }
+
+ void return_void() {
+ Promise_.SetValue();
+ }
+
+ private:
+ NThreading::TPromise<void> Promise_ = NThreading::NewPromise();
+ };
+};
+
+template<typename T, typename... Args>
+struct std::coroutine_traits<NThreading::TFuture<T>, Args...> {
+ struct promise_type {
+ NThreading::TFuture<T> get_return_object() {
+ return Promise_.GetFuture();
+ }
+
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+
+ void unhandled_exception() {
+ Promise_.SetException(std::current_exception());
+ }
+
+ void return_value(auto&& val) {
+ Promise_.SetValue(std::forward<decltype(val)>(val));
+ }
+
+ private:
+ NThreading::TPromise<T> Promise_ = NThreading::NewPromise<T>();
+ };
+};
+
+template<typename T>
+struct TFutureAwaitable {
+ NThreading::TFuture<T> Future;
+
+ TFutureAwaitable(NThreading::TFuture<T> future)
+ : Future{future}
+ {
+ }
+
+ bool await_ready() const noexcept {
+ return Future.HasValue() || Future.HasException();
+ }
+
+ void await_suspend(auto h) noexcept {
+ /*
+ * This library assumes that resume never throws an exception.
+ * This assumption is made due to the fact that the users of these library in most cases do not need to write their own coroutine handlers,
+ * and all coroutine handlers provided by the library do not throw exception from resume.
+ *
+ * WARNING: do not change subscribe to apply or something other here, creating an extra future state degrades performance.
+ */
+ Future.NoexceptSubscribe(
+ [h](auto) mutable noexcept {
+ h();
+ }
+ );
+ }
+
+ decltype(auto) await_resume() {
+ return Future.GetValue();
+ }
+};
+
+template<typename T>
+auto operator co_await(const NThreading::TFuture<T>& future) {
+ return TFutureAwaitable{future};
+}
+
+namespace NThreading {
+
+ template<typename T>
+ auto AsAwaitable(const NThreading::TFuture<T>& fut) {
+ return operator co_await(fut);
+ }
+
+} // namespace NThreading