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

Overview

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.

You might also like...
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

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/

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

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

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

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

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" #

📚 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

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-

Comments
  • Allow direct co_yield of a pointer

    Allow direct co_yield of a pointer

    This PR allows co_yielding a pointer. Now this does not work:

    tl::generator<int*> gen() {
      int i = ...;
      co_yield &i;
      //workaround:
      int* ret = &i;
      co_yield ret;
    }
    
    opened by Loghorn 0
  • 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]

    opened by tchaikov 0
  • 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'
    
    opened by unit-a-user 0
  • 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 :-(

    opened by wouterbeek 0
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

Eric Niebler 3.6k Jan 4, 2023
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

Sy Brand 64 Dec 20, 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

Al Azif 9 Oct 4, 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

Feabhas Ltd. 12 Dec 2, 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

Dmitry Atamanov 4 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

Rabia Alhaffar 118 Dec 6, 2022
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

Sepehr Taghdisian 29 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

e_t 9 Oct 10, 2022