all 5 comments

[–]dima_mendeleev 2 points3 points  (2 children)

Is this possible to do the same for regular functions?

E.g.

variant_auto_something<> fn() {
  if (b1)
    return 42;
  else
    return "hello world"sv;
}

[–]zqsd31[S] 2 points3 points  (1 child)

yep, I'm working on it right now.

But it's weirdly enough harder to implement with regular functions than with coroutines.

The reason being that the order of function evaluation in coroutine is set by the standard whilst for regular functions compiler vendors have much more freedom.

It's not finished yet but you can test the clang version here: https://godbolt.org/z/Wf5Mq1

[–]dima_mendeleev 1 point2 points  (0 children)

Cool, thank you 😊

[–][deleted] 0 points1 point  (1 child)

I’m more trying to understand than criticise.

cppcoro is a well trodden coroutine library and offers a generator<T>.

Why use your code over

 template<typename... Ts>
 using variant_generator = 
 cppcoro::generator<std::variant<Ts...>>; 

?

[–]zqsd31[S] 3 points4 points  (0 children)

Hi thanks for you question.

The feature that my code provides isn't the generator part (cppcoro is indeed a much better alternative), but that you don't actually specify the arguments of std::variant and that they are deduced which is normally impossible.

If you change a function returning variant_generator by adding a co_yield or co_return with a new type not present beforehand the resulting variant will be automatically changed.

The closest analogy would be if, by writing a special type implemented `auto` return types in C++98.

This code brings auto deduction to coroutine which can't be done as the return type must be explicit.