Информация об изменениях

Сообщение Re[8]: C++20 coroutines (co_await) от 16.01.2021 6:30

Изменено 16.01.2021 6:33 Evgeny.Panasyuk

Re[8]: C++20 coroutines (co_await)
Здравствуйте, х, Вы писали:

EP>>Там конкретный тип promise, а не конкретной корутины. Разные корутины выдающие один и тот же promise, могут иметь разный размер, так как имеют разный размер фрейма.

х>size_t окружения передаётся в new.

Ага, в рантайме, отсюда и неизбежная аллокация в общем случае.

х>В общем по мне ты сложно как-то пишешь. Попробую моими словами. Проблемы две: 1. вынужденный new, который идёт как следствие того, что надо в фиксированный размер запихнуть нефиксированный локальный фрейм. Вторая проблема, что нельзя включить шаблонную оптимизацию.


Ну ещё проблема в том, что за счёт стирания типов, мы внезапно теряем информацию о типах, что снижает общую типизацию, и возможности по перегрузке/специализации после того как корутина уже создана.

х>Давай обсуждать какие есть варианты для решения.

х>Допустим замена:
х>
х>template<typename U, typename... Locals>
х>    void await_suspend(U hndl, Locals args...) noexcept {
      this->>_future.then(hndl, std::forward<Locals>(args));
х>

х>то что хочется?
х>В общем какое предложение?

Что-то типа, и в таком исполнении тип _future дожен зависить от конкретной корутины.

Если в общем, то например хочется чтобы вместо:
template<typename R, typename... Args> struct coroutine_traits;
Было:
template<typename ConcreteCourotine, typename R, typename... Args> struct coroutine_traits;
Где соответвенно тип ConcreteCourotine будет разным для:
generator<int> iota(int n);
и для
generator<int> even(int n);
Несмотря на то что у них одинаковые типы параметров и результата, потому что их локальные переменные И код могут быть разным.

Если же потребуется type-erasure (которое является нормальной техникой, у того же std::function есть вполне реальные и обоснованные варианты применения, с этим никто не спорит), то вложенные типы (::promise_type) coroutine_traits будут не зависеть от типа ConcreteCourotine, либо зависеть но как-то выборочно (например все корутины размером до 32 байт будут давать один тип, все остальные другой, то есть тип стирается но "частично").

Но это о том как поправить вот эту вот реализацию. А принципиально проблемы нет, так как это УЖЕ работает на макросах, и вполне понятно как сделать механическую трансформацию кода из описания корутины в класс конкретного типа, собественно макросы и помогают делать эту трансформацию, конечно в меру своих ограниченных возможностей.
Re[8]: C++20 coroutines (co_await)
Здравствуйте, х, Вы писали:

EP>>Там конкретный тип promise, а не конкретной корутины. Разные корутины выдающие один и тот же promise, могут иметь разный размер, так как имеют разный размер фрейма.

х>size_t окружения передаётся в new.

Ага, в рантайме, отсюда и неизбежная аллокация в общем случае.

х>В общем по мне ты сложно как-то пишешь. Попробую моими словами. Проблемы две: 1. вынужденный new, который идёт как следствие того, что надо в фиксированный размер запихнуть нефиксированный локальный фрейм. Вторая проблема, что нельзя включить шаблонную оптимизацию.


Ну ещё проблема в том, что за счёт стирания типов, мы внезапно теряем информацию о типах, что снижает общую типизацию, и возможности по перегрузке/специализации после того как корутина уже создана.

х>Давай обсуждать какие есть варианты для решения.

х>Допустим замена:
х>
х>template<typename U, typename... Locals>
х>    void await_suspend(U hndl, Locals args...) noexcept {
      this->>_future.then(hndl, std::forward<Locals>(args));
х>

х>то что хочется?
х>В общем какое предложение?

Что-то типа, и в таком исполнении тип _future дожен зависить от конкретной корутины.

Если в общем, то например хочется чтобы вместо:
template<typename R, typename... Args> struct coroutine_traits;
Было:
template<typename ConcreteCoroutine, typename R, typename... Args> struct coroutine_traits;
Где соответвенно тип ConcreteCoroutine будет разным для:
generator<int> iota(int n);
и для
generator<int> even(int n);
Несмотря на то что у них одинаковые типы параметров и результата, потому что их локальные переменные И код могут быть разным.

Если же потребуется type-erasure (которое является нормальной техникой, у того же std::function есть вполне реальные и обоснованные варианты применения, с этим никто не спорит), то вложенные типы (::promise_type) coroutine_traits будут не зависеть от типа ConcreteCoroutine, либо зависеть но как-то выборочно (например все корутины размером до 32 байт будут давать один тип, все остальные другой, то есть тип стирается но "частично").

Но это о том как поправить вот эту вот реализацию. А принципиально проблемы нет, так как это УЖЕ работает на макросах, и вполне понятно как сделать механическую трансформацию кода из описания корутины в класс конкретного типа, собественно макросы и помогают делать эту трансформацию, конечно в меру своих ограниченных возможностей.