Skip to content

Commit bf5b900

Browse files
added nothrow support.
1 parent 820f9c3 commit bf5b900

File tree

6 files changed

+99
-4
lines changed

6 files changed

+99
-4
lines changed

Diff for: include/boost/cobalt/detail/generator.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,8 @@ struct generator_promise
355355
return generator->receiver && generator->receiver->awaited_from.get() == nullptr;
356356
}
357357

358-
auto await_suspend(std::coroutine_handle<generator_promise> h) noexcept
358+
template<std::derived_from<generator_promise> Promise>
359+
auto await_suspend(std::coroutine_handle<Promise> h) noexcept
359360
{
360361
std::coroutine_handle<void> res = std::noop_coroutine();
361362
if (generator->receiver && generator->receiver->awaited_from.get() != nullptr)

Diff for: include/boost/cobalt/detail/promise.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,8 @@ struct cobalt_promise
351351
return promise->receiver && promise->receiver->awaited_from.get() == nullptr;
352352
}
353353

354-
std::coroutine_handle<void> await_suspend(std::coroutine_handle<cobalt_promise> h) noexcept
354+
template<std::derived_from<cobalt_promise> Promise_>
355+
std::coroutine_handle<void> await_suspend(std::coroutine_handle<Promise_> h) noexcept
355356
{
356357
std::coroutine_handle<void> res = std::noop_coroutine();
357358
if (promise->receiver && promise->receiver->awaited_from.get() != nullptr)

Diff for: include/boost/cobalt/detail/task.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,9 @@ struct task_promise
336336
return promise->receiver && promise->receiver->awaited_from.get() == nullptr;
337337
}
338338

339+
template<std::derived_from<task_promise> Promise>
339340
BOOST_NOINLINE
340-
auto await_suspend(std::coroutine_handle<task_promise> h) noexcept
341+
auto await_suspend(std::coroutine_handle<Promise> h) noexcept
341342
{
342343
std::coroutine_handle<void> res = std::noop_coroutine();
343344
if (promise->receiver && promise->receiver->awaited_from.get() != nullptr)

Diff for: include/boost/cobalt/nothrow.hpp

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// Copyright (c) 2023 Klemens Morgenstern ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
8+
#ifndef BOOST_COBALT_NOTHROW_HPP
9+
#define BOOST_COBALT_NOTHROW_HPP
10+
11+
#include <boost/cobalt/config.hpp>
12+
13+
#include <boost/system/result.hpp>
14+
#include <boost/system/error_code.hpp>
15+
#include <boost/system/errc.hpp>
16+
17+
#include <coroutine>
18+
19+
namespace boost::cobalt
20+
{
21+
22+
template<typename Handle>
23+
struct nothrow : boost::system::result<Handle>
24+
{
25+
nothrow(Handle && h) : boost::system::result<Handle>(boost::system::in_place_value, std::move(h)) {}
26+
nothrow() : boost::system::result<Handle>(boost::system::in_place_error,
27+
make_error_code(boost::system::errc::not_enough_memory))
28+
{}
29+
};
30+
31+
}
32+
33+
template<typename Handle, typename ... Args>
34+
struct std::coroutine_traits<boost::cobalt::nothrow<Handle>, Args...>
35+
{
36+
struct promise_type : std::coroutine_traits<Handle, Args...>::promise_type
37+
{
38+
static void* operator new(std::size_t sz) noexcept
39+
{
40+
return ::operator new(sz, std::nothrow);
41+
}
42+
43+
static void operator delete(void * raw, const std::size_t size) noexcept
44+
{
45+
#if defined(__cpp_sized_deallocation)
46+
::operator delete(raw, size);
47+
#else
48+
::operator delete(raw, size);
49+
#endif
50+
}
51+
52+
boost::cobalt::nothrow<Handle> get_return_object()
53+
{
54+
return std::coroutine_traits<Handle, Args...>::promise_type::get_return_object();
55+
}
56+
57+
static boost::cobalt::nothrow<Handle> get_return_object_on_allocation_failure()
58+
{
59+
return {};
60+
}
61+
62+
};
63+
};
64+
65+
#endif //BOOST_COBALT_NOTHROW_HPP

Diff for: test/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ add_executable(boost_cobalt_main main.cpp)
1010
add_executable(boost_cobalt_main_compile main_compile.cpp)
1111
add_executable(boost_cobalt_basic_tests
1212
async_for.cpp test_main.cpp promise.cpp with.cpp op.cpp handler.cpp join.cpp race.cpp this_coro.cpp leaf.cpp
13-
channel.cpp generator.cpp run.cpp task.cpp gather.cpp wait_group.cpp wrappers.cpp left_race.cpp
13+
channel.cpp generator.cpp run.cpp task.cpp gather.cpp wait_group.cpp wrappers.cpp left_race.cpp nothrow.cpp
1414
strand.cpp fork.cpp thread.cpp any_completion_handler.cpp detached.cpp monotonic_resource.cpp sbo_resource.cpp)
1515

1616
target_link_libraries(boost_cobalt_main Boost::cobalt)

Diff for: test/nothrow.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Copyright (c) 2024 Klemens Morgenstern ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
8+
#include <boost/cobalt/nothrow.hpp>
9+
10+
#include <boost/cobalt/task.hpp>
11+
12+
#include <boost/test/unit_test.hpp>
13+
#include "test.hpp"
14+
15+
boost::cobalt::nothrow<boost::cobalt::task<void>> p1() {co_return ;}
16+
boost::cobalt::nothrow<boost::cobalt::task<void>> p2()
17+
{
18+
volatile char data[1000000000000ull];
19+
co_return ;
20+
}
21+
22+
BOOST_AUTO_TEST_CASE(nothrow_)
23+
{
24+
BOOST_CHECK(p1().has_value());
25+
BOOST_CHECK(p2().has_error());
26+
}
27+

0 commit comments

Comments
 (0)