mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-16 04:08:10 +00:00
Added thirdparty: boost library
This commit is contained in:
+156
@@ -0,0 +1,156 @@
|
||||
// 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_WRAPPER_HPP
|
||||
#define BOOST_COBALT_WRAPPER_HPP
|
||||
|
||||
#include <boost/cobalt/this_coro.hpp>
|
||||
#include <boost/cobalt/concepts.hpp>
|
||||
#include <boost/cobalt/detail/util.hpp>
|
||||
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <coroutine>
|
||||
#include <utility>
|
||||
#if BOOST_COBALT_NO_SELF_DELETE
|
||||
#include <boost/asio/consign.hpp>
|
||||
#endif
|
||||
namespace boost::cobalt::detail
|
||||
{
|
||||
|
||||
template<typename Allocator>
|
||||
struct partial_promise_base
|
||||
{
|
||||
template<typename CompletionToken>
|
||||
void * operator new(const std::size_t size, CompletionToken & token)
|
||||
{
|
||||
// gcc: 168 40
|
||||
// clang: 144 40
|
||||
return allocate_coroutine(size, asio::get_associated_allocator(token));
|
||||
}
|
||||
|
||||
template<typename Executor, typename CompletionToken>
|
||||
void * operator new(const std::size_t size, Executor &, CompletionToken & token)
|
||||
{
|
||||
// gcc: 120 8 16
|
||||
// clang: 96 8 16
|
||||
return allocate_coroutine(size, asio::get_associated_allocator(token));
|
||||
}
|
||||
|
||||
void operator delete(void * raw, const std::size_t size)
|
||||
{
|
||||
deallocate_coroutine<Allocator>(raw, size);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct partial_promise_base<std::allocator<void>> {};
|
||||
|
||||
|
||||
template<> struct partial_promise_base<void> {};
|
||||
template<typename T> struct partial_promise_base<std::allocator<T>> {};
|
||||
|
||||
// alloc options are two: allocator or aligned storage
|
||||
template<typename Allocator = void>
|
||||
struct partial_promise : partial_promise_base<Allocator>
|
||||
{
|
||||
auto initial_suspend() noexcept
|
||||
{
|
||||
return std::suspend_always();
|
||||
}
|
||||
|
||||
auto final_suspend() noexcept
|
||||
{
|
||||
return std::suspend_never();
|
||||
}
|
||||
|
||||
void return_void() {}
|
||||
};
|
||||
|
||||
template<typename Allocator = void>
|
||||
struct post_coroutine_promise : partial_promise<Allocator>
|
||||
{
|
||||
template<typename CompletionToken>
|
||||
auto yield_value(CompletionToken cpl)
|
||||
{
|
||||
struct awaitable_t
|
||||
{
|
||||
CompletionToken cpl;
|
||||
constexpr bool await_ready() noexcept { return false; }
|
||||
BOOST_NOINLINE
|
||||
auto await_suspend(std::coroutine_handle<void> h) noexcept
|
||||
{
|
||||
auto c = std::move(cpl);
|
||||
if (this_thread::has_executor())
|
||||
detail::self_destroy(h, asio::get_associated_executor(c, this_thread::get_executor()));
|
||||
else
|
||||
detail::self_destroy(h, asio::get_associated_executor(c));
|
||||
|
||||
asio::post(std::move(c));
|
||||
}
|
||||
|
||||
constexpr void await_resume() noexcept {}
|
||||
};
|
||||
return awaitable_t{std::move(cpl)};
|
||||
}
|
||||
|
||||
std::coroutine_handle<post_coroutine_promise<Allocator>> get_return_object()
|
||||
{
|
||||
return std::coroutine_handle<post_coroutine_promise<Allocator>>::from_promise(*this);
|
||||
}
|
||||
|
||||
void unhandled_exception()
|
||||
{
|
||||
detail::self_destroy(std::coroutine_handle<post_coroutine_promise<Allocator>>::from_promise(*this));
|
||||
throw;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <typename T, typename ... Args>
|
||||
struct coroutine_traits<coroutine_handle<boost::cobalt::detail::post_coroutine_promise<T>>, Args...>
|
||||
{
|
||||
using promise_type = boost::cobalt::detail::post_coroutine_promise<T>;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
namespace boost::cobalt::detail
|
||||
{
|
||||
|
||||
|
||||
template <typename CompletionToken>
|
||||
auto post_coroutine(CompletionToken token)
|
||||
-> std::coroutine_handle<post_coroutine_promise<asio::associated_allocator_t<CompletionToken>>>
|
||||
{
|
||||
co_yield std::move(token);
|
||||
}
|
||||
|
||||
template <asio::execution::executor Executor, typename CompletionToken>
|
||||
auto post_coroutine(Executor exec, CompletionToken token)
|
||||
-> std::coroutine_handle<post_coroutine_promise<asio::associated_allocator_t<CompletionToken>>>
|
||||
{
|
||||
co_yield asio::bind_executor(exec, std::move(token));
|
||||
}
|
||||
|
||||
template <with_get_executor Context, typename CompletionToken>
|
||||
auto post_coroutine(Context &ctx, CompletionToken token)
|
||||
-> std::coroutine_handle<post_coroutine_promise<asio::associated_allocator_t<CompletionToken>>>
|
||||
{
|
||||
co_yield asio::bind_executor(ctx.get_executor(), std::move(token));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //BOOST_COBALT_WRAPPER_HPP
|
||||
Reference in New Issue
Block a user