jbaldwin / libcoro

C++20 coroutine library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Explore std::variant for coro::task return value / exception

jbaldwin opened this issue · comments

@a858438680 committed a nice change to use less memory in coro::task, I'd like to explore using a more type safe std::variant since we are on C++20 instead of unsigned char[] directly. I'd want to test to make sure the size difference is the same, but I think it'll reduce some of the metaprogramming to determine which type is larger and allocating based off of that.

TEST_CASE("task promise sizeof", "[task]")
{
    REQUIRE(sizeof(coro::detail::promise<void>) == sizeof(std::coroutine_handle<>) + sizeof(std::exception_ptr));
    REQUIRE(sizeof(coro::detail::promise<int32_t>) == sizeof(std::coroutine_handle<>) + sizeof(std::variant<int32_t, std::exception_ptr>));
    REQUIRE(sizeof(coro::detail::promise<int64_t>) == sizeof(std::coroutine_handle<>) + sizeof(std::variant<int64_t, std::exception_ptr>));
    REQUIRE(sizeof(coro::detail::promise<std::vector<int64_t>>) == sizeof(std::coroutine_handle<>) + sizeof(std::variant<std::vector<int64_t>, std::exception_ptr>));
}

The output of this is identical on main and the branch I'm working on, so std::variant is being smart enough under the hood for space requirements.

My current std::variant implementation has unfortunately regressed with 1 extra copy on the copy only struct, trying to root that out.

I've managed to get rid of the placement new on the std::variant and reduced the number of moves and copies to the original solution.