blob: 5f1be4e00f4fc3731ba5f42c88c5d3fa381ac108 [file] [log] [blame]
// { dg-do run }
#include "../coro.h"
struct pt_b
{
std::suspend_never initial_suspend() const noexcept { return {}; }
std::suspend_never final_suspend() const noexcept { return {}; }
void unhandled_exception() const noexcept {}
constexpr static void return_void () noexcept {}
};
int called_yv_op = 0;
int v;
struct pt_c : pt_b
{
struct yv
{
auto operator ()(int x){
PRINTF("call to operator yield val with %d\n", x);
called_yv_op++;
v = x;
return std::suspend_never{};
}
};
using handle_t = std::coroutine_handle<pt_c>;
auto get_return_object() noexcept { return handle_t::from_promise(*this); }
yv yield_value;
};
int called_lambda = 0;
struct pt_d : pt_b
{
using handle_t = std::coroutine_handle<pt_d>;
auto get_return_object() noexcept { return handle_t::from_promise(*this); }
static constexpr auto yield_value = [] (int x) -> std::suspend_never
{
PRINTF("call to lambda yield val %d\n", x);
called_lambda++;
v = x;
return {};
};
};
template <> struct std::coroutine_traits<pt_c::handle_t>
{ using promise_type = pt_c; };
static pt_c::handle_t foo ()
{
co_yield 5;
}
template <> struct std::coroutine_traits<pt_d::handle_t>
{ using promise_type = pt_d; };
static pt_d::handle_t bar ()
{
co_yield 3;
}
int main ()
{
/* These 'coroutines' run to completion imediately, like a regular fn. */
foo ();
if (v != 5)
{
PRINT ("foo failed to yield v");
abort ();
}
bar ();
if (v != 3)
{
PRINT ("bar failed to yield v");
abort ();
}
if (called_yv_op != 1 || called_lambda != 1)
{
PRINT ("Failed to call one of the yield_value cases");
abort ();
}
}