Реализация генераторов через макросы на C++

Энтузиасты написали генераторы на C++, которые базируются на do-нотации, которая тоже сделана на макросах. Реализация открыта под лицензией MIT.


   // Без do-нотации

   auto result = ::bind(mx, [&](auto&& x) {
     return ::bind(my, [&](auto&& y) {
       return make_value(x + y);
     });
   });

   // С do-нотацией
   auto result = DO(
     LET x IS(mx);
     LET y IS(my);
     return make_value(x + y);
   );

Пример кода с генераторами:


   // Allocation free generators

   constexpr auto my_generator() {
     return GENERATOR((int i), (.i = 0), // или GENERATOR_LOOPHOLES
       YIELD(42);
       WHILE(i != 10) (
         YIELD(i);
         ++i;
       )
       return end‹int, 16›();
     );
   }

   static_assert(std::ranges::equal(my_generator(),
                                 std::array{42, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));

   int main() {
     auto gen = my_generator();
     gen.i = 3;
     std::println("{}", gen);  // prints [42, 3, 4, 5, 6, 7, 8, 9]
     /*
     for (auto i : gen) {
       std::println("{}", i);
     }
     */
   }

С генераторами определяется функция bind и база в виде generator_continuation. Каждый bind теперь работает лениво, а не вычисляет всё сразу. В коде предоставлены 2 версии кода — на базе виртуальных функций и на базе аналога std::variant через технику Type Loopholes для большей производительности.

Источник: http://www.opennet.ru/opennews/art.shtml?num=65079