mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-18 21:28:10 +00:00
Added thirdparty: boost library
This commit is contained in:
+154
@@ -0,0 +1,154 @@
|
||||
// Copyright (c) 2022 Klemens D. Morgenstern
|
||||
//
|
||||
// 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 BOOST_COBALT_DETAIL_WITH_HPP
|
||||
#define BOOST_COBALT_DETAIL_WITH_HPP
|
||||
|
||||
#include <boost/cobalt/concepts.hpp>
|
||||
#include <boost/cobalt/this_coro.hpp>
|
||||
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
|
||||
namespace boost::cobalt::detail
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
struct [[nodiscard]] with_impl
|
||||
{
|
||||
struct promise_type;
|
||||
|
||||
bool await_ready() { return false;}
|
||||
|
||||
template<typename Promise>
|
||||
BOOST_NOINLINE auto await_suspend(std::coroutine_handle<Promise> h) -> std::coroutine_handle<promise_type>;
|
||||
inline T await_resume();
|
||||
|
||||
private:
|
||||
with_impl(promise_type & promise) : promise(promise) {}
|
||||
promise_type & promise;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct with_promise_value
|
||||
{
|
||||
std::optional<T> result;
|
||||
|
||||
void return_value(std::optional<T> && value)
|
||||
{
|
||||
if (value) // so non-move-assign types work
|
||||
result.emplace(std::move(*value));
|
||||
}
|
||||
|
||||
T get_result()
|
||||
{
|
||||
return std::move(result).value();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct with_promise_value<void>
|
||||
{
|
||||
void return_void() {}
|
||||
void get_result() {}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct with_impl<T>::promise_type
|
||||
: with_promise_value<T>,
|
||||
enable_awaitables<promise_type>,
|
||||
enable_await_allocator<promise_type>
|
||||
{
|
||||
using enable_awaitables<promise_type>::await_transform;
|
||||
using enable_await_allocator<promise_type>::await_transform;
|
||||
|
||||
|
||||
using executor_type = executor;
|
||||
const executor_type & get_executor() const {return *exec;}
|
||||
std::optional<executor_type> exec;
|
||||
|
||||
with_impl get_return_object()
|
||||
{
|
||||
return with_impl{*this};
|
||||
}
|
||||
|
||||
std::exception_ptr e;
|
||||
void unhandled_exception()
|
||||
{
|
||||
e = std::current_exception();
|
||||
}
|
||||
|
||||
std::suspend_always initial_suspend() {return {};}
|
||||
|
||||
struct final_awaitable
|
||||
{
|
||||
promise_type *promise;
|
||||
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BOOST_NOINLINE
|
||||
auto await_suspend(std::coroutine_handle<promise_type> h) noexcept -> std::coroutine_handle<void>
|
||||
{
|
||||
return std::coroutine_handle<void>::from_address(h.promise().awaited_from.address());
|
||||
}
|
||||
|
||||
void await_resume() noexcept
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
auto final_suspend() noexcept
|
||||
{
|
||||
return final_awaitable{this};
|
||||
}
|
||||
using cancellation_slot_type = asio::cancellation_slot;
|
||||
cancellation_slot_type get_cancellation_slot() const {return slot_;}
|
||||
asio::cancellation_slot slot_;
|
||||
|
||||
std::coroutine_handle<void> awaited_from{nullptr};
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T with_impl<T>::await_resume()
|
||||
{
|
||||
auto e = promise.e;
|
||||
auto res = std::move(promise.get_result());
|
||||
std::coroutine_handle<promise_type>::from_promise(promise).destroy();
|
||||
if (e)
|
||||
std::rethrow_exception(e);
|
||||
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void with_impl<void>::await_resume()
|
||||
{
|
||||
auto e = promise.e;
|
||||
std::coroutine_handle<promise_type>::from_promise(promise).destroy();
|
||||
if (e)
|
||||
std::rethrow_exception(e);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Promise>
|
||||
auto with_impl<T>::await_suspend(std::coroutine_handle<Promise> h) -> std::coroutine_handle<promise_type>
|
||||
{
|
||||
if constexpr (requires (Promise p) {p.get_executor();})
|
||||
promise.exec.emplace(h.promise().get_executor());
|
||||
else
|
||||
promise.exec.emplace(this_thread::get_executor());
|
||||
|
||||
if constexpr (requires (Promise p) {p.get_cancellation_slot();})
|
||||
promise.slot_ = h.promise().get_cancellation_slot();
|
||||
|
||||
promise.awaited_from = h;
|
||||
return std::coroutine_handle<promise_type>::from_promise(promise);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //BOOST_COBALT_DETAIL_WITH_HPP
|
||||
Reference in New Issue
Block a user