Single-header, ranges-compatible generator type built on C++20 coroutines

generator

Single-header, ranges-compatible generator type built with C++20 coroutines.

Documentation Status

A generator allows implementing sequence producers which are terse and avoid creating the whole sequence in memory.

For example, if you were to need a sequence of the first n integers, you could generate a std::vector of them. This implementation would be simple, but would have to produce the whole sequence in memory. To avoid this, you could instead write an iterator or range which generates them lazily. However, writing iterators and ranges comes with a lot of boilerplate. Generators have the benefits of both:

tl::generator<int> firstn(std::size_t n) {
   for (auto i = 0; i < n; ++i) {
      co_yield i;
   }
}

You could then use this generator like so:

for (auto i : firstn(10)) {
   std::cout << i;
}

Generators can also create infinite sequences:

tl::generator<int> iota(int i = 0) {
  while(true) {
    co_yield i;
    ++i;
  }
}

You can then pipe this to a range to process it:

for (auto i : iota() | std::views::take(10)) {
   std::cout << i;
}

Compiler support

tl::generator has been tested on Visual Studio 2019 version 16.9 and GCC 10.


CC0

To the extent possible under law, Sy Brand has waived all copyright and related or neighboring rights to the optional library. This work is published from: United Kingdom.

Similar Resources

A single-header C/C++ library for parsing and evaluation of arithmetic expressions

ceval A C/C++ header for parsing and evaluation of arithmetic expressions. [README file is almost identical to that of the ceval library] Functions ac

Aug 27, 2022

A single-header, new syntax for C & C++

sea A new syntax for C & C++, in one header file sea is a new syntax for C & C++. It can be used by adding the following line of code to a .c, or .cc/

Nov 19, 2021

base64 single header encode/decode

b64.h base64 single header encode/decode #include stdio.h #include "b64.h" // strings are stored on the heap, don't forget to free() them int main(i

Jul 27, 2022

Tuibox - A single-header terminal UI (TUI) library, capable of creating mouse-driven, interactive applications on the command line.

Tuibox - A single-header terminal UI (TUI) library, capable of creating mouse-driven, interactive applications on the command line.

tuibox tuibox ("toybox") is a single-header terminal UI library, capable of creating mouse-driven, interactive applications on the command line. It is

Sep 22, 2022

Single header lib for JPEG encoding. Public domain. C99. stb style.

tiny_jpeg.h A header-only public domain implementation of Baseline JPEG compression. Features: stb-style header only library. Does not do dynamic allo

Sep 18, 2022

Single-header VMT hook class using vfptr swap method

Single-header C++ VMT hooking (vfptr swap) Supports RAII Unit tested with Catch2 Tested on x86/x64, MSVC and Clang/LLVM VMT size calculation Windows-o

Mar 22, 2022

A single header C++ wasm frontend library leveraging Emscripten

A single header C++ wasm frontend library leveraging Emscripten

Livid Livid is a single header C++ wasm frontend library leveraging Emscripten. Usage The code looks something like this: #include "livid/livid.hpp" #

Jul 12, 2022

📚 single header utf8 string functions for C and C++

📚 utf8.h A simple one header solution to supporting utf8 strings in C and C++. Functions provided from the C header string.h but with a utf8* prefix

Sep 22, 2022

Single-header multi-platform tablet library

EasyTab Single-header multi-platform tablet library, for easy integration of drawing tablets (e.g. Wacom) into your code. Features Single-file header-

Sep 18, 2022
Comments
  • add typename before dependent type name

    add typename before dependent type name

    to address the compiling failures from Clang-14, like:

    ./generator.hpp:76:29: error: missing 'typename' prior to dependent type name 'promise_type::value_type' using value_type = promise_type::value_type; ^~~~~~~~~~~~~~~~~~~~~~~~ typename ./generator.hpp:77:33: error: missing 'typename' prior to dependent type name 'promise_type::reference_type' using reference_type = promise_type::reference_type; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ typename ./generator.hpp:78:31: error: missing 'typename' prior to dependent type name 'promise_type::pointer_type' using pointer_type = promise_type::pointer_type; ^~~~~~~~~~~~~~~~~~~~~~~~~~ typename

    Signed-off-by: Kefu Chai [email protected]

  • Incompatible with Clang 13

    Incompatible with Clang 13

    I tried to compile with Clang 13 our project with generator...

    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(44,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(45,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(45,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(45,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(59,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(59,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(59,15): error : no type named 'suspend_always' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(73,35): error : no template named 'coroutine_handle' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(76,29): error : missing 'typename' prior to dependent type name 'promise_type::value_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(77,33): error : missing 'typename' prior to dependent type name 'promise_type::reference_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(78,31): error : missing 'typename' prior to dependent type name 'promise_type::pointer_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(73,35): error : no template named 'coroutine_handle' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(76,29): error : missing 'typename' prior to dependent type name 'promise_type::value_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(77,33): error : missing 'typename' prior to dependent type name 'promise_type::reference_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(78,31): error : missing 'typename' prior to dependent type name 'promise_type::pointer_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(73,35): error : no template named 'coroutine_handle' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(76,29): error : missing 'typename' prior to dependent type name 'promise_type::value_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(77,33): error : missing 'typename' prior to dependent type name 'promise_type::reference_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(78,31): error : missing 'typename' prior to dependent type name 'promise_type::pointer_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(118,19): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(118,19): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(118,19): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(120,10): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(120,10): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(120,10): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(123,32): error : no template named 'coroutine_handle' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(123,32): error : no template named 'coroutine_handle' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(123,32): error : no template named 'coroutine_handle' in namespace 'std'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(156,26): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(156,26): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(156,26): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(158,7): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(158,7): error : unknown type name 'handle_type'
    2>C:\VULKAN\Alter\submodules\include\tl/generator.hpp(158,7): error : unknown type name 'handle_type'
    
  • Unable to compile with GCC 11.1

    Unable to compile with GCC 11.1

    I'm unable to build this with GCC 11.1 because of the following error:

    $ cmake --build .
    [ 33%] Building CXX object CMakeFiles/tl-generator-catch-main.dir/catch.main.cpp.o
    [ 33%] Built target tl-generator-catch-main
    [ 66%] Building CXX object CMakeFiles/tl-generator-test-test.dir/tests/test.cpp.o
    In file included from /home/wouter/cpp/generator/include/tl/generator.hpp:28,
                     from /home/wouter/cpp/generator/tests/test.cpp:1:
    /usr/include/c++/11/ranges: In instantiation of ‘constexpr bool std::ranges::operator==(std::ranges::take_view<tl::generator<int> >::_CI<false>&, const std::ranges::take_view<tl::generator<int> >::_Sentinel<false>&)’:
    /home/wouter/cpp/generator/tests/test.cpp:32:51:   required from here
    /usr/include/c++/11/ranges:1775:48: error: passing ‘std::ranges::take_view<tl::generator<int> >::_CI<false>’ {aka ‘const std::counted_iterator<tl::generator<int>::iterator>’} as ‘this’ argument discards qualifiers [-fpermissive]
     1775 |           { return __y.count() == 0 || __y.base() == __x._M_end; }
          |                                        ~~~~~~~~^~
    In file included from /usr/include/c++/11/iterator:63,
                     from /usr/include/c++/11/ranges:43,
                     from /home/wouter/cpp/generator/include/tl/generator.hpp:28,
                     from /home/wouter/cpp/generator/tests/test.cpp:1:
    /usr/include/c++/11/bits/stl_iterator.h:2151:7: note:   in call to ‘constexpr _It std::counted_iterator<_It>::base() && [with _It = tl::generator<int>::iterator]’
     2151 |       base() &&
          |       ^~~~
    make[2]: *** [CMakeFiles/tl-generator-test-test.dir/build.make:76: CMakeFiles/tl-generator-test-test.dir/tests/test.cpp.o] Error 1
    make[1]: *** [CMakeFiles/Makefile2:130: CMakeFiles/tl-generator-test-test.dir/all] Error 2
    make: *** [Makefile:166: all] Error 2
    

    Does this have something to do with constness? I cannot figure it out :-(

Range library for C++14/17/20, basis for C++20's std::ranges

range-v3 Range library for C++14/17/20. This code was the basis of a formal proposal to add range support to the C++ standard library. That proposal e

Sep 21, 2022
Ranges that didn't make C++20

ranges Implementations of ranges that didn't make C++20. Coded live on Twitch. Types tl::enumerate_view/tl::views::enumerate A view which lets you ite

Aug 18, 2022
Supporting code for coroutines blog.

coroutines-blog Demonstration code for the Feabhas coroutines blog. Build the demos using make. Remove generated executables with make clean. Generate

Jul 25, 2022
A single file, single function, header to make notifications on the PS4 easier

Notifi Synopsis Adds a single function notifi(). It functions like printf however the first arg is the image to use (NULL and any invalid input should

Aug 24, 2022
Header-only ECMAScript (JavaScript) compatible regular expression engine

SRELL (std::regex-like library) is a regular expression template library for C++ and has native support for UTF-8, UTF-16, and UTF-32. This is up-to-d

Mar 11, 2022
Collection of cross-platform single-header C libraries for doing a lot of stuff! (Still WIP)

ice_libs Collection of cross-platform single-header C libraries for doing a lot of stuff! (Still WIP) Brief ice_libs is collection of Single-Header C

Sep 16, 2022
stackwalkerc - Windows single header stack walker in C (DbgHelp.DLL)
 stackwalkerc - Windows single header stack walker in C (DbgHelp.DLL)

stackwalkerc - Windows single header stack walker in C (DbgHelp.DLL) Features Can be used in C or C++ code Super simple API Single header library make

Jul 4, 2022
A single-header C/C++ library for parsing and evaluation of arithmetic expressions

ceval A C/C++ header for parsing and evaluation of arithmetic expressions. [README file is almost identical to that of the ceval library] Functions ac

Aug 27, 2022