Skip to content

Commit

Permalink
added nothrow support.
Browse files Browse the repository at this point in the history
  • Loading branch information
klemens-morgenstern committed Mar 14, 2024
1 parent 820f9c3 commit bf5b900
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 4 deletions.
3 changes: 2 additions & 1 deletion include/boost/cobalt/detail/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ struct generator_promise
return generator->receiver && generator->receiver->awaited_from.get() == nullptr;
}

auto await_suspend(std::coroutine_handle<generator_promise> h) noexcept
template<std::derived_from<generator_promise> Promise>
auto await_suspend(std::coroutine_handle<Promise> h) noexcept
{
std::coroutine_handle<void> res = std::noop_coroutine();
if (generator->receiver && generator->receiver->awaited_from.get() != nullptr)
Expand Down
3 changes: 2 additions & 1 deletion include/boost/cobalt/detail/promise.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,8 @@ struct cobalt_promise
return promise->receiver && promise->receiver->awaited_from.get() == nullptr;
}

std::coroutine_handle<void> await_suspend(std::coroutine_handle<cobalt_promise> h) noexcept
template<std::derived_from<cobalt_promise> Promise_>
std::coroutine_handle<void> await_suspend(std::coroutine_handle<Promise_> h) noexcept
{
std::coroutine_handle<void> res = std::noop_coroutine();
if (promise->receiver && promise->receiver->awaited_from.get() != nullptr)
Expand Down
3 changes: 2 additions & 1 deletion include/boost/cobalt/detail/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,9 @@ struct task_promise
return promise->receiver && promise->receiver->awaited_from.get() == nullptr;
}

template<std::derived_from<task_promise> Promise>
BOOST_NOINLINE
auto await_suspend(std::coroutine_handle<task_promise> h) noexcept
auto await_suspend(std::coroutine_handle<Promise> h) noexcept
{
std::coroutine_handle<void> res = std::noop_coroutine();
if (promise->receiver && promise->receiver->awaited_from.get() != nullptr)
Expand Down
65 changes: 65 additions & 0 deletions include/boost/cobalt/nothrow.hpp
Original file line number Diff line number Diff line change
@@ -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 <boost/cobalt/config.hpp>

#include <boost/system/result.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/errc.hpp>

#include <coroutine>

namespace boost::cobalt
{

template<typename Handle>
struct nothrow : boost::system::result<Handle>
{
nothrow(Handle && h) : boost::system::result<Handle>(boost::system::in_place_value, std::move(h)) {}
nothrow() : boost::system::result<Handle>(boost::system::in_place_error,
make_error_code(boost::system::errc::not_enough_memory))
{}
};

}

template<typename Handle, typename ... Args>
struct std::coroutine_traits<boost::cobalt::nothrow<Handle>, Args...>
{
struct promise_type : std::coroutine_traits<Handle, Args...>::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, size);
#endif
}

boost::cobalt::nothrow<Handle> get_return_object()
{
return std::coroutine_traits<Handle, Args...>::promise_type::get_return_object();
}

static boost::cobalt::nothrow<Handle> get_return_object_on_allocation_failure()
{
return {};
}

};
};

#endif //BOOST_COBALT_NOTHROW_HPP
2 changes: 1 addition & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
27 changes: 27 additions & 0 deletions test/nothrow.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/cobalt/nothrow.hpp>

#include <boost/cobalt/task.hpp>

#include <boost/test/unit_test.hpp>
#include "test.hpp"

boost::cobalt::nothrow<boost::cobalt::task<void>> p1() {co_return ;}
boost::cobalt::nothrow<boost::cobalt::task<void>> p2()
{
volatile char data[1000000000000ull];
co_return ;
}

BOOST_AUTO_TEST_CASE(nothrow_)
{
BOOST_CHECK(p1().has_value());
BOOST_CHECK(p2().has_error());
}

0 comments on commit bf5b900

Please sign in to comment.