summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/include/asio/experimental/detail/coro_traits.hpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/include/asio/experimental/detail/coro_traits.hpp')
-rw-r--r--3rdparty/asio/include/asio/experimental/detail/coro_traits.hpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/3rdparty/asio/include/asio/experimental/detail/coro_traits.hpp b/3rdparty/asio/include/asio/experimental/detail/coro_traits.hpp
new file mode 100644
index 00000000000..a2b31cb952e
--- /dev/null
+++ b/3rdparty/asio/include/asio/experimental/detail/coro_traits.hpp
@@ -0,0 +1,183 @@
+//
+// experimental/detail/coro_traits.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2021 Klemens D. Morgenstern
+// (klemens dot morgenstern at gmx dot net)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_EXPERIMENTAL_DETAIL_CORO_TRAITS_HPP
+#define ASIO_EXPERIMENTAL_DETAIL_CORO_TRAITS_HPP
+
+#include "asio/detail/config.hpp"
+#include <optional>
+#include <variant>
+#include "asio/any_io_executor.hpp"
+
+namespace asio {
+namespace experimental {
+namespace detail {
+
+template <class From, class To>
+concept convertible_to = std::is_convertible_v<From, To> &&
+ requires(std::add_rvalue_reference_t<From> (&f)()) {static_cast<To>(f()); };
+
+template <typename T>
+concept decays_to_executor = execution::executor<std::decay_t<T>>;
+
+template <typename T>
+concept execution_context = requires (T& t)
+{
+ {t.get_executor()} -> decays_to_executor;
+};
+
+template <typename Yield, typename Return>
+struct coro_result
+{
+ using type = std::variant<Yield, Return>;
+};
+
+template <typename Yield>
+struct coro_result<Yield, void>
+{
+ using type = std::optional<Yield>;
+};
+
+template <typename Return>
+struct coro_result<void, Return>
+{
+ using type = Return;
+};
+
+template <typename YieldReturn>
+struct coro_result<YieldReturn, YieldReturn>
+{
+ using type = YieldReturn;
+};
+
+template <>
+struct coro_result<void, void>
+{
+ using type = void;
+};
+
+template <typename Yield, typename Return>
+using coro_result_t = typename coro_result<Yield, Return>::type;
+
+template <typename Result, bool IsNoexcept>
+struct coro_handler;
+
+template <>
+struct coro_handler<void, false>
+{
+ using type = void(std::exception_ptr);
+};
+
+template <>
+struct coro_handler<void, true>
+{
+ using type = void();
+};
+
+template <typename T>
+struct coro_handler<T, false>
+{
+ using type = void(std::exception_ptr, T);
+};
+
+template <typename T>
+struct coro_handler<T, true>
+{
+ using type = void(T);
+};
+
+template <typename Result, bool IsNoexcept>
+using coro_handler_t = typename coro_handler<Result, IsNoexcept>::type;
+
+template <typename Yield, typename Return, typename Executor>
+struct coro_traits
+{
+ using input_type = void;
+ using yield_type = Yield;
+ using return_type = Return;
+ using result_type = coro_result_t<yield_type, return_type>;
+ using signature_type = result_type();
+ constexpr static bool is_noexcept = false;
+ using error_type = std::conditional_t<is_noexcept, void, std::exception_ptr>;
+ using completion_handler = coro_handler_t<result_type, is_noexcept>;
+};
+
+template <typename T, typename Return, typename Executor>
+struct coro_traits<T(), Return, Executor>
+{
+ using input_type = void;
+ using yield_type = T;
+ using return_type = Return;
+ using result_type = coro_result_t<yield_type, return_type>;
+ using signature_type = result_type();
+ constexpr static bool is_noexcept = false;
+ using error_type = std::conditional_t<is_noexcept, void, std::exception_ptr>;
+ using completion_handler = coro_handler_t<result_type, is_noexcept>;
+};
+
+template <typename T, typename Return, typename Executor>
+struct coro_traits<T() noexcept, Return, Executor>
+{
+ using input_type = void;
+ using yield_type = T;
+ using return_type = Return;
+ using result_type = coro_result_t<yield_type, return_type>;
+ using signature_type = result_type();
+ constexpr static bool is_noexcept = true;
+ using error_type = std::conditional_t<is_noexcept, void, std::exception_ptr>;
+ using completion_handler = coro_handler_t<result_type, is_noexcept>;
+};
+
+template <typename T, typename U, typename Return, typename Executor>
+struct coro_traits<T(U), Return, Executor>
+{
+ using input_type = U;
+ using yield_type = T;
+ using return_type = Return;
+ using result_type = coro_result_t<yield_type, return_type>;
+ using signature_type = result_type(input_type);
+ constexpr static bool is_noexcept = false;
+ using error_type = std::conditional_t<is_noexcept, void, std::exception_ptr>;
+ using completion_handler = coro_handler_t<result_type, is_noexcept>;
+};
+
+template <typename T, typename U, typename Return, typename Executor>
+struct coro_traits<T(U) noexcept, Return, Executor>
+{
+ using input_type = U;
+ using yield_type = T;
+ using return_type = Return;
+ using result_type = coro_result_t<yield_type, return_type>;
+ using signature_type = result_type(input_type);
+ constexpr static bool is_noexcept = true;
+ using error_type = std::conditional_t<is_noexcept, void, std::exception_ptr>;
+ using completion_handler = coro_handler_t<result_type, is_noexcept>;
+};
+
+
+template <typename Executor>
+struct coro_traits<void() noexcept, void, Executor>
+{
+ using input_type = void;
+ using yield_type = void;
+ using return_type = void;
+ using result_type = coro_result_t<yield_type, return_type>;
+ using signature_type = result_type(input_type);
+ constexpr static bool is_noexcept = true;
+ using error_type = std::conditional_t<is_noexcept, void, std::exception_ptr>;
+ using completion_handler = coro_handler_t<result_type, is_noexcept>;
+};
+
+} // namespace detail
+} // namespace experimental
+} // namespace asio
+
+#endif // ASIO_EXPERIMENTAL_DETAIL_CORO_TRAITS_HPP