Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Никакое не ЧТД
EP>Что мешает вот это:
EP>EP>future<void> coroutine()
EP>{
EP> int x = await foo;
EP> char y = await bar;
EP> cout << x << " " << y << endl;
EP>}
EP>
Преобразовать вот в это:
EP>EP>struct coroutine : asio::coroutine
EP>{
EP> int x;
EP> char y;
EP> void operator()()
EP> {
EP> reenter(*this)
EP> {
EP> await(x, foo); // x = await foo;
EP> await(y, bar); // y = await bar;
EP> cout << x << " " << y << endl;
EP> }
EP> };
EP>};
EP>
?
То, что future<void> — это value-type, который владеет через shared над future_shared_state.
EP>Более того, в C# именно подобное преобразование и происходит.
Конечно именно так. Но там TaskAwaiter — это value-type, просто фасад над Task. Зато сам Task создаётся в куче. И поданное ему continuation — это делегат, лямбда для которого тоже создаётся в куче.
V>>Так вот, если уши торчат, как в твоём примере, то нафига это тянуть в стандарт?
EP>Я не предлагаю в стандарт тянуть эмуляцию на макросах. Ещё раз, я показываю как оно может быть устроенно внутри.
Я прекрасно понимаю, как оно устроено изнутри. Но я, хоть убей, не могу понять, как ты собрался реализовать свои желания с т.з. системы типов C++?
Вот у нас есть тип std::future, который устроен примерно так:
template<class T>
class future {
...
shared_ptr<shared_state> shared_state_;
}
Т.е. внутри него всего одно поле и sizeof(future<>) скорее всего совпадет с sizeof(shared_state_).
Где ты предлагаешь разместить аналог своего asio::coroutine в future<>? Я бы его разместил в объекте-наследнике того самого shared_state, который, в свою очередь, создаётся на куче.
Другое дело:
iterator<T> generate() resumable {
yield return 1;
yield return 2;
};
Т.к. тип iterator<> еще не специфирован, вполне возможно, что у него будет некое зарезервированное поле, в котором можно поместить целочисленную переменную — состояние автомата-корутины.
НО! Это всё еще не так просто. Посмотри по твоей же ссылке на поле private object <>t__stack.
Если твоя легковесная корутина будет содержать в себе другие корутины, то нужно эмулировать стек для их правильного обхода. И тут уже, извини, но без выделения памяти в куче — никак.