From b4651939277663abbeb5fc1bd7275f1203b7e123 Mon Sep 17 00:00:00 2001 From: Klemens Morgenstern Date: Thu, 14 Mar 2024 10:33:20 +0800 Subject: [PATCH] added nothrow support. --- include/boost/cobalt/detail/generator.hpp | 3 +- include/boost/cobalt/detail/promise.hpp | 3 +- include/boost/cobalt/detail/task.hpp | 3 +- include/boost/cobalt/nothrow.hpp | 65 +++++++++++++++++++++++ test/CMakeLists.txt | 2 +- test/nothrow.cpp | 27 ++++++++++ 6 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 include/boost/cobalt/nothrow.hpp create mode 100644 test/nothrow.cpp diff --git a/include/boost/cobalt/detail/generator.hpp b/include/boost/cobalt/detail/generator.hpp index 2c2760cb..053ca0de 100644 --- a/include/boost/cobalt/detail/generator.hpp +++ b/include/boost/cobalt/detail/generator.hpp @@ -355,7 +355,8 @@ struct generator_promise return generator->receiver && generator->receiver->awaited_from.get() == nullptr; } - auto await_suspend(std::coroutine_handle h) noexcept + template Promise> + auto await_suspend(std::coroutine_handle h) noexcept { std::coroutine_handle res = std::noop_coroutine(); if (generator->receiver && generator->receiver->awaited_from.get() != nullptr) diff --git a/include/boost/cobalt/detail/promise.hpp b/include/boost/cobalt/detail/promise.hpp index e9dc78ed..7a7bdf42 100644 --- a/include/boost/cobalt/detail/promise.hpp +++ b/include/boost/cobalt/detail/promise.hpp @@ -351,7 +351,8 @@ struct cobalt_promise return promise->receiver && promise->receiver->awaited_from.get() == nullptr; } - std::coroutine_handle await_suspend(std::coroutine_handle h) noexcept + template Promise_> + std::coroutine_handle await_suspend(std::coroutine_handle h) noexcept { std::coroutine_handle res = std::noop_coroutine(); if (promise->receiver && promise->receiver->awaited_from.get() != nullptr) diff --git a/include/boost/cobalt/detail/task.hpp b/include/boost/cobalt/detail/task.hpp index d5afb39a..f5fa6100 100644 --- a/include/boost/cobalt/detail/task.hpp +++ b/include/boost/cobalt/detail/task.hpp @@ -336,8 +336,9 @@ struct task_promise return promise->receiver && promise->receiver->awaited_from.get() == nullptr; } + template Promise> BOOST_NOINLINE - auto await_suspend(std::coroutine_handle h) noexcept + auto await_suspend(std::coroutine_handle h) noexcept { std::coroutine_handle res = std::noop_coroutine(); if (promise->receiver && promise->receiver->awaited_from.get() != nullptr) diff --git a/include/boost/cobalt/nothrow.hpp b/include/boost/cobalt/nothrow.hpp new file mode 100644 index 00000000..5bb7148e --- /dev/null +++ b/include/boost/cobalt/nothrow.hpp @@ -0,0 +1,65 @@ +// +// Copyright (c) 2023 Klemens Morgenstern (klemens.morgenstern@gmx.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 BOOST_COBALT_NOTHROW_HPP +#define BOOST_COBALT_NOTHROW_HPP + +#include + +#include +#include +#include + +#include + +namespace boost::cobalt +{ + +template +struct nothrow : boost::system::result +{ + nothrow(Handle && h) : boost::system::result(boost::system::in_place_value, std::move(h)) {} + nothrow() : boost::system::result(boost::system::in_place_error, + make_error_code(boost::system::errc::not_enough_memory)) + {} +}; + +} + +template +struct std::coroutine_traits, Args...> +{ + struct promise_type : std::coroutine_traits::promise_type + { + static void* operator new(std::size_t sz) noexcept + { + return ::operator new(sz, std::nothrow); + } + + static void operator delete(void * raw, const std::size_t size) noexcept + { +#if defined(__cpp_sized_deallocation) + ::operator delete(raw, size); +#else + ::operator delete(raw); +#endif + } + + boost::cobalt::nothrow get_return_object() + { + return std::coroutine_traits::promise_type::get_return_object(); + } + + static boost::cobalt::nothrow get_return_object_on_allocation_failure() + { + return {}; + } + + }; +}; + +#endif //BOOST_COBALT_NOTHROW_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 032ff54b..86a095fc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,7 +10,7 @@ add_executable(boost_cobalt_main main.cpp) add_executable(boost_cobalt_main_compile main_compile.cpp) add_executable(boost_cobalt_basic_tests async_for.cpp test_main.cpp promise.cpp with.cpp op.cpp handler.cpp join.cpp race.cpp this_coro.cpp leaf.cpp - channel.cpp generator.cpp run.cpp task.cpp gather.cpp wait_group.cpp wrappers.cpp left_race.cpp + channel.cpp generator.cpp run.cpp task.cpp gather.cpp wait_group.cpp wrappers.cpp left_race.cpp nothrow.cpp strand.cpp fork.cpp thread.cpp any_completion_handler.cpp detached.cpp monotonic_resource.cpp sbo_resource.cpp) target_link_libraries(boost_cobalt_main Boost::cobalt) diff --git a/test/nothrow.cpp b/test/nothrow.cpp new file mode 100644 index 00000000..4bc47318 --- /dev/null +++ b/test/nothrow.cpp @@ -0,0 +1,27 @@ +// +// Copyright (c) 2024 Klemens Morgenstern (klemens.morgenstern@gmx.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) +// + +#include + +#include + +#include +#include "test.hpp" + +boost::cobalt::nothrow> p1() {co_return ;} +boost::cobalt::nothrow> p2() +{ + volatile char data[1000000000000ull]; + co_return ; +} + +BOOST_AUTO_TEST_CASE(nothrow_) +{ + BOOST_CHECK(p1().has_value()); + BOOST_CHECK(p2().has_error()); +} +