Coro - Single-header library facilities for C++2a Coroutines

Overview

coro

This is a collection of single-header library facilities for C++2a Coroutines.

coro/include/

co_future.h

Provides co_future<T>, which is like std::future<T> but models Awaitable.

co_optional.h

Provides co_optional<T>, which is like std::optional<T> but is awaitable. This is based on code originally by Toby Allsopp. Notice that co_optional<T> is awaitable only in coroutine contexts where the return type is itself co_optional<U> — not, say, task<U> or generator<U> — and therefore co_optional<T> does not model the P1288R0 Awaitable concept.

concepts.h

Provides definitions for the concepts and type-traits from Lewis Baker's P1288R0, based on his own reference implementation.

  • concept Awaitable
  • concept AwaitableOf<R>
  • concept Awaiter
  • concept AwaiterOf<R>
  • awaiter_type_t<T>
  • await_result_t<T>
  • get_awaiter(Awaitable t)

gor_generator.h

Gor Nishanov's generator<R>. The difference between this one and "mcnellis_generator.h" is that this one stores the value of coro_.done() in a bool member variable. That change makes it more friendly to the compiler's optimizer. This is the only generator that works as intended with "disappearing_coroutine.cpp".

This generator is move-only.

mcnellis_generator.h

James McNellis's int_generator example from "Introduction to C++ Coroutines" (CppCon 2016), templatized into generator<T>. I had to fill in some boilerplate he didn't show, such as iterator comparison, return_void/unhandled_exception, and several constructors. Any mistakes are likely mine, not his.

This generator is neither moveable nor copyable.

shared_generator.h, unique_generator.h

unique_generator<R> is basically equivalent to cppcoro::generator<R>. It expresses unique ownership of a coroutine handle, which means it is move-only. This is the most natural way to implement a generator object, but it does have the downside that it is not a range-v3 viewable_range.

shared_generator<R> is basically equivalent to range-v3's ranges::experimental::generator<R>. It expresses reference-counted ownership of a coroutine handle, so that it is copyable. It is a full viewable_range and interoperates correctly with range-v3.

These generators' end() methods return a sentinel type instead of iterator, which means that these generators do not interoperate with the C++17 STL algorithms.

resumable_thing.h

James McNellis's resumable_thing example from "Introduction to C++ Coroutines" (CppCon 2016).

sync_wait.h

Lewis Baker's implementation of P1171 sync_wait(Awaitable t). Suppose you're in main(), and you have a task<int> that you've received from a coroutine. You can't co_await it, because as soon as you use the co_await keyword you turn into a coroutine yourself. If (and only if?) the coroutine is being executed in another thread, then you can pass the task off to sync_wait.

TODO: this needs some example code!

task.h, gor_task.h

task<R> is basically equivalent to cppcoro::task<R>. It models Awaitable (as defined in "concepts.h").

"gor_task.h" provides another implementation of task<R>, as shown in Gor Nishanov's "C++ Coroutines: Under the Covers" (CppCon 2016).

TODO: this needs some example code!

examples/

co_optional.cpp

Simple examples of using co_optional monadic operations with co_await and co_return.

co_optional_tests.cpp

Toby Allsopp's monadic optional comes with a test suite. This is that test suite.

disappearing_coroutine.cpp

Gor Nishanov's example of passing a generator to std::accumulate, from his talk "C++ Coroutines: Under the Covers" (CppCon 2016). Clang can optimize this down to a single printf; but only if you use "gor_generator.h". If you use one of the generators that doesn't cache coro_.done() in a data member, Clang will not be able to optimize it.

generate_ints.cpp

A very simple example of unique_generator with co_yield.

generator_as_viewable_range.cpp

Similar to generate_ints.cpp, this example demonstrates mixing Coroutines with Ranges. It uses shared_generator (which models ranges::viewable_range) and pipes the generator object through rv::take(10).

mcnellis_generator.cpp

James McNellis's int_generator example from "Introduction to C++ Coroutines" (CppCon 2016).

mcnellis_resumable_thing.cpp

James McNellis's first resumable_thing example from "Introduction to C++ Coroutines" (CppCon 2016).

mcnellis_resumable_thing_dangling.cpp

James McNellis's second resumable_thing example from "Introduction to C++ Coroutines" (CppCon 2016), showing the interleaved execution of two named_counter coroutines.

We show both McNellis's working named_counter, which captures a std::string by value, and a broken_named_counter that captures a std::string_view and thus suffers from a subtle dangling-reference bug whose effects are visible in the output.

p1288r0_concepts.cpp

Lewis Baker's reference implementation of P1288R0 comes with a test suite. This is that test suite.

pythagorean_triples_generator.cpp

Eric's Famous Pythagorean Triples, but using a shared_generator that co_yields tuples. This is almost identical to generator_as_viewable_range.cpp; it's just a slightly more interesting application.

Issues
  • Question: about final_suspend::await_suspend

    Question: about final_suspend::await_suspend

    https://github.com/Quuxplusone/coro/blob/313235400c14ccdce6b8b161d29cef3c3d090ab3/include/coro/gor_task.h#L24

    Why can't you write return me_->waiter;? I tested it and got sigfault.

    opened by CarterLi 0
  • clang segfault

    clang segfault

    https://coro.godbolt.org/z/ElU-Ij

    This is a compiler bug, but passing it on to you first, in case you want to isolate/reduce and submit a bug-report to llvm (otherwise feel free to just close).

    opened by ast-al 0
Owner
Arthur O'Dwyer
Arthur O'Dwyer
C++20 coroutines-based cooperative multitasking library

?? Coop Coop is a C++20 coroutines-based library to support cooperative multitasking in the context of a multithreaded application. The syntax will be

Jeremy Ong 74 Aug 11, 2022
Cppcoro - A library of C++ coroutine abstractions for the coroutines TS

CppCoro - A coroutine library for C++ The 'cppcoro' library provides a large set of general-purpose primitives for making use of the coroutines TS pro

Lewis Baker 2.4k Aug 14, 2022
Modern concurrency for C++. Tasks, executors, timers and C++20 coroutines to rule them all

concurrencpp, the C++ concurrency library concurrencpp is a tasking library for C++ allowing developers to write highly concurrent applications easily

David Haim 1k Aug 10, 2022
Discrete-event simulation in C++20 using coroutines

SimCpp20 SimCpp20 is a discrete-event simulation framework for C++20. It is similar to SimPy and aims to be easy to set up and use. Processes are defi

Felix Schütz 28 Apr 29, 2022
Open source PHP extension for Async IO, Coroutines and Fibers

Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++ for PHP. Ope

Open Swoole 521 Aug 6, 2022
C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)

Continuable is a C++14 library that provides full support for: lazy async continuation chaining based on callbacks (then) and expression templates, ca

Denis Blank 757 Aug 5, 2022
A fast single-producer, single-consumer lock-free queue for C++

A single-producer, single-consumer lock-free queue for C++ This mini-repository has my very own implementation of a lock-free queue (that I designed f

Cameron 2.7k Aug 5, 2022
A bounded single-producer single-consumer wait-free and lock-free queue written in C++11

SPSCQueue.h A single producer single consumer wait-free and lock-free fixed size queue written in C++11. Example SPSCQueue<int> q(2); auto t = std::th

Erik Rigtorp 509 Aug 7, 2022
Single header asymmetric stackful cross-platform coroutine library in pure C.

minicoro Minicoro is single-file library for using asymmetric coroutines in C. The API is inspired by Lua coroutines but with C use in mind. The proje

Eduardo Bart 313 Aug 15, 2022
C++20's jthread for C++11 and later in a single-file header-only library

jthread lite: C++20's jthread for C++11 and later A work in its infancy. Suggested by Peter Featherstone. Contents Example usage In a nutshell License

Martin Moene 44 Jul 16, 2022
Mx - C++ coroutine await, yield, channels, i/o events (single header + link to boost)

mx C++11 coroutine await, yield, channels, i/o events (single header + link to boost). This was originally part of my c++ util library kit, but I'm se

Grady O'Connell 4 Sep 21, 2019
Px - Single header C++ Libraries for Thread Scheduling, Rendering, and so on...

px 'PpluX' Single header C++(11/14) Libraries Name Code Description px_sched px_sched.h Task oriented scheduler. See more px_render px_render.h Multit

PpluX 442 Aug 12, 2022
A competitive programming helper tool, which packages included libraries into a single file, suitable for online judges.

cpack Cpack is a competitive programming helper tool, which packages the main source file along with included libraries into a single file, suitable f

PetarMihalj 11 Apr 22, 2022
Fork of rpmalloc to be used with single thread applications and old C compilers

srpmalloc - Small rpmalloc This is a fork of rpmalloc, with the intent to be used in single threaded applications only, with old C99 compilers, and in

Eduardo Bart 6 Apr 30, 2022
Coroutine - C++11 single .h asymmetric coroutine implementation via ucontext / fiber

C++11 single .h asymmetric coroutine implementation API in namespace coroutine: routine_t create(std::function<void()> f); void destroy(routine_t id);

null 379 Jun 30, 2022
Xenium is a noninteractive protocol for producing and redeeming single-use claim codes

Xenium Xenium is a noninteractive protocol for producing and redeeming single-use claim codes. What this means in practice is that you can have a devi

Nick Johnson 30 Jun 23, 2022
A framework for decentralised production and redemption of single-use codes

Xenium Xenium is a noninteractive protocol for producing and redeeming single-use claim codes. What this means in practice is that you can have a devi

Nick Johnson 30 Jun 23, 2022
A header-only C++ library for task concurrency

transwarp Doxygen documentation transwarp is a header-only C++ library for task concurrency. It allows you to easily create a graph of tasks where eve

Christian Blume 590 Aug 6, 2022
Header-only library for multithreaded programming

CsLibGuarded Introduction The CsLibGuarded library is a standalone header only library for multithreaded programming. This library provides templated

CopperSpice 178 Jul 18, 2022