{"id":13730188,"url":"https://github.com/Quuxplusone/coro","last_synced_at":"2025-05-08T02:32:02.847Z","repository":{"id":47077421,"uuid":"194988371","full_name":"Quuxplusone/coro","owner":"Quuxplusone","description":"Single-header library facilities for C++2a Coroutines","archived":false,"fork":false,"pushed_at":"2022-02-13T16:12:34.000Z","size":48,"stargazers_count":80,"open_issues_count":1,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-09T16:53:49.243Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Quuxplusone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-03T05:54:54.000Z","updated_at":"2025-03-30T00:45:49.000Z","dependencies_parsed_at":"2022-08-27T22:50:15.318Z","dependency_job_id":null,"html_url":"https://github.com/Quuxplusone/coro","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quuxplusone%2Fcoro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quuxplusone%2Fcoro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quuxplusone%2Fcoro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Quuxplusone%2Fcoro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Quuxplusone","download_url":"https://codeload.github.com/Quuxplusone/coro/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252986891,"owners_count":21836250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T02:01:11.152Z","updated_at":"2025-05-08T02:32:02.607Z","avatar_url":"https://github.com/Quuxplusone.png","language":"C++","readme":"# coro\nThis is a collection of single-header library facilities for C++2a Coroutines.\n\n## coro/include/\n\n### co_future.h\n\nProvides `co_future\u003cT\u003e`, which is like `std::future\u003cT\u003e` but models `Awaitable`.\n\n### co_optional.h\n\nProvides `co_optional\u003cT\u003e`, which is like `std::optional\u003cT\u003e` but is awaitable.\nThis is based on [code originally by Toby Allsopp](https://github.com/toby-allsopp/coroutine_monad/#using-coroutines-for-monadic-composition).\nNotice that `co_optional\u003cT\u003e` is awaitable only in coroutine contexts where the\nreturn type is itself `co_optional\u003cU\u003e` — not, say, `task\u003cU\u003e` or `generator\u003cU\u003e` —\nand therefore `co_optional\u003cT\u003e` does _not_ model the P1288R0 `Awaitable` concept.\n\n### concepts.h\n\nProvides definitions for the concepts and type-traits from Lewis Baker's P1288R0,\nbased on his own reference implementation.\n\n- `concept Awaitable`\n- `concept AwaitableOf\u003cR\u003e`\n- `concept Awaiter`\n- `concept AwaiterOf\u003cR\u003e`\n- `awaiter_type_t\u003cT\u003e`\n- `await_result_t\u003cT\u003e`\n- `get_awaiter(Awaitable t)`\n\n### gor_generator.h\n\nGor Nishanov's `generator\u003cR\u003e`. The difference between this one and \"mcnellis_generator.h\"\nis that this one stores the value of `coro_.done()` in a bool member variable. That change\nmakes it more friendly to the compiler's optimizer. This is the only generator that works\nas intended with \"disappearing_coroutine.cpp\".\n\nThis generator is move-only.\n\n### mcnellis_generator.h\n\nJames McNellis's `int_generator` example from \"Introduction to C++ Coroutines\" (CppCon 2016),\ntemplatized into `generator\u003cT\u003e`. I had to fill in some boilerplate he didn't show, such\nas iterator comparison, `return_void`/`unhandled_exception`, and several constructors.\nAny mistakes are likely mine, not his.\n\nThis generator is neither moveable nor copyable.\n\n### shared_generator.h, unique_generator.h\n\n`unique_generator\u003cR\u003e` is basically equivalent to `cppcoro::generator\u003cR\u003e`.\nIt expresses unique ownership of a coroutine handle, which means it is move-only.\nThis is the most natural way to implement a generator object, but it does have the\ndownside that it is not a range-v3 `viewable_range`.\n\n`shared_generator\u003cR\u003e` is basically equivalent to range-v3's `ranges::experimental::generator\u003cR\u003e`.\nIt expresses _reference-counted_ ownership of a coroutine handle, so that it is copyable.\nIt is a full `viewable_range` and interoperates correctly with range-v3.\n\nThese generators' `end()` methods return a sentinel type instead of `iterator`,\nwhich means that these generators do not interoperate with the C++17 STL algorithms.\n\n### resumable_thing.h\n\nJames McNellis's `resumable_thing` example from \"Introduction to C++ Coroutines\" (CppCon 2016).\n\n### sync_wait.h\n\nLewis Baker's implementation of P1171 `sync_wait(Awaitable t)`.\nSuppose you're in `main()`, and you have a `task\u003cint\u003e` that you've received from a coroutine.\nYou can't `co_await` it, because as soon as you use the `co_await` keyword you\nturn into a coroutine yourself. If (and only if?) the coroutine is being executed in another thread,\nthen you can pass the task off to `sync_wait`.\n\nTODO: this needs some example code!\n\n### task.h, gor_task.h\n\n`task\u003cR\u003e` is basically equivalent to `cppcoro::task\u003cR\u003e`.\nIt models `Awaitable` (as defined in \"concepts.h\").\n\n\"gor_task.h\" provides another implementation of `task\u003cR\u003e`, as shown in Gor Nishanov's\n\"C++ Coroutines: Under the Covers\" (CppCon 2016).\n\nTODO: this needs some example code!\n\n## examples/\n\n### co_optional.cpp\n\nSimple examples of using `co_optional` monadic operations with `co_await` and `co_return`.\n\n### co_optional_tests.cpp\n\nToby Allsopp's monadic `optional` comes with a test suite.\nThis is that test suite.\n\n### disappearing_coroutine.cpp\n\nGor Nishanov's example of passing a generator to `std::accumulate`, from\nhis talk \"C++ Coroutines: Under the Covers\" (CppCon 2016). Clang can optimize\nthis down to a single `printf`; but only if you use \"gor_generator.h\". If you use\none of the generators that doesn't cache `coro_.done()` in a data member, Clang will\nnot be able to optimize it.\n\n### generate_ints.cpp\n\nA very simple example of `unique_generator` with `co_yield`.\n\n### generator_as_viewable_range.cpp\n\nSimilar to `generate_ints.cpp`, this example demonstrates mixing Coroutines with Ranges.\nIt uses `shared_generator` (which models `ranges::viewable_range`)\nand pipes the generator object through `rv::take(10)`.\n\n### mcnellis_generator.cpp\n\nJames McNellis's `int_generator` example from \"Introduction to C++ Coroutines\" (CppCon 2016).\n\n### mcnellis_resumable_thing.cpp\n\nJames McNellis's first `resumable_thing` example from \"Introduction to C++ Coroutines\" (CppCon 2016).\n\n### mcnellis_resumable_thing_dangling.cpp\n\nJames McNellis's second `resumable_thing` example from \"Introduction to C++ Coroutines\" (CppCon 2016),\nshowing the interleaved execution of two `named_counter` coroutines.\n\nWe show both McNellis's working `named_counter`, which captures a `std::string` by value,\n_and_ a `broken_named_counter` that captures a `std::string_view` and thus suffers from a\nsubtle dangling-reference bug whose effects are visible in the output.\n\n### p1288r0_concepts.cpp\n\nLewis Baker's reference implementation of P1288R0 comes with a test suite.\nThis is that test suite.\n\n### pythagorean_triples_generator.cpp\n\n[Eric's Famous Pythagorean Triples](http://ericniebler.com/2018/12/05/standard-ranges/),\nbut using a `shared_generator` that `co_yield`s tuples.\nThis is almost identical to `generator_as_viewable_range.cpp`; it's just\na slightly more interesting application.\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FQuuxplusone%2Fcoro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FQuuxplusone%2Fcoro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FQuuxplusone%2Fcoro/lists"}