Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ repos:
rev: v0.5.2
hooks:
- id: beman-tidy
args: [".", "--verbose"]
args: [".", "--verbose", "--require-all"]

# Clang-format for C++
# This brings in a portable version of clang-format.
Expand Down
9 changes: 6 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ include(FetchContent)

FetchContent_Declare(
execution
# FETCHCONTENT_SOURCE_DIR_EXECUTION ${CMAKE_SOURCE_DIR}/../execution
FETCHCONTENT_SOURCE_DIR_EXECUTION
${CMAKE_SOURCE_DIR}/../execution
GIT_REPOSITORY https://github.com/bemanproject/execution
GIT_TAG 7df0f75
GIT_TAG cd3211e
Comment on lines 33 to +38
SYSTEM
FIND_PACKAGE_ARGS
0.2.0
Expand All @@ -46,9 +47,11 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(execution)

add_subdirectory(src/beman/task)
add_library(beman.task STATIC)
add_library(beman::task ALIAS beman.task)

add_subdirectory(src/beman/task)

#===============================================================================
# NOTE: this must be done before tests! CK
include(infra/cmake/beman-install-library.cmake)
Expand Down
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# beman.task: Beman Library Implementation of `task` (P3552)

<!--
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

![Continuous Integration Tests](https://github.com/bemanproject/task/actions/workflows/ci_tests.yml/badge.svg)
![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp26.svg)
![Coverage](https://coveralls.io/repos/github/bemanproject/task/badge.svg?branch=main)
[![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg)](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#the-beman-library-maturity-model)
<!-- markdownlint-disable line-length -->
[![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg)](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#the-beman-library-maturity-model)![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp26.svg)[![Coverage](https://coveralls.io/repos/github/bemanproject/task/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/task?branch=main)[![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/e1sjsT46r)
<!-- markdownlint-restore -->

`beman::execution::task<T, Context>` is a class template which
is used as the the type of coroutine tasks. The corresponding objects
Expand All @@ -16,7 +14,7 @@ type which becomes a `set_value_t(T)` completion signatures. The
second template argument (`Context`) provides a way to configure
the behavior of the coroutine. By default it can be left alone.

**Implements**: `std::execution::task` proposed in [Add a Coroutine Lazy Type (P3552)](https://wg21.link/P3552).
**Implements**: [Add a Coroutine Lazy Type (P3552)](https://wg21.link/P3552).

**Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#under-development-and-not-yet-ready-for-production-use)

Expand Down
48 changes: 24 additions & 24 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-affinity.cpp'>c++now-affinity.cpp</a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_affinity.cpp'>cppnow_affinity.cpp</a>
<a href='https://godbolt.org/z/8qEG5x7sz'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo scheduler affinity
</summary>

The example program
[`c++now-affinity.cpp`](https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-affinity.cpp)
uses [`demo::thread_loop`](../examples/demo-thread_loop.hpp) to demonstrate
[`cppnow_affinity.cpp`](https://github.com/bemanproject/task/blob/main/examples/cppnow_affinity.cpp)
uses [`demo::thread_loop`](../examples/demo_thread_loop.hpp) to demonstrate
the behavior of _scheduler affinity_: the idea is that scheduler
affinity causes the coroutine to resume on the same scheduler as
the one the coroutine was started on. The program implements three
Expand Down Expand Up @@ -59,7 +59,7 @@ the `inline_scheduler` doesn't do any actual scheduling.

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-allocator.cpp'><code>c++now-allocator.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_allocator.cpp'><code>cppnow_allocator.cpp</code></a>
<a href='https://godbolt.org/z/719v7en6a'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo allocator use
</summary>
Expand All @@ -83,13 +83,13 @@ The second use explicitly specifies the memory resource

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-basic.cpp'><code>c++now-basic.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_basic.cpp'><code>cppnow_basic.cpp</code></a>
<a href='https://godbolt.org/z/7Pn5TEhfK'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo basic <code>task</code> use
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-basic.cpp'><code>c++now-basic.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_basic.cpp'><code>cppnow_basic.cpp</code></a>
shows some basic use of a `task`:

1. The coroutine `basic` just `co_await`s the awaiter `std::suspend_never{}` which immediately completes.
Expand All @@ -105,26 +105,26 @@ shows some basic use of a `task`:

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-cancel.cpp'><code>c++now-cancel.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_cancel.cpp'><code>cppnow_cancel.cpp</code></a>
<a href='https://godbolt.org/z/vx4PqYvE6'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo how a <code>task</code> can actively cancel the work
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-cancel.cpp'><code>c++now-cancel.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_cancel.cpp'><code>cppnow_cancel.cpp</code></a>
shows a coroutine `co_await`ing `just_stopped()` which results in the coroutine getting cancelled. The coroutine will
complete with `set_stopped()`.
</details>

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-errors.cpp'><code>c++now-errors.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_errors.cpp'><code>cppnow_errors.cpp</code></a>
<a href='https://godbolt.org/z/95Mhr5MGn'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo how to handle errors within <code>task</code>
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-errors.cpp'><code>c++now-errors.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_errors.cpp'><code>cppnow_errors.cpp</code></a>
shows examples of how to handle errors within a coroutine:

- The coroutine `error_result` simply `co_await`s a sender producing an error (`just_error(17)`). When
Expand All @@ -139,13 +139,13 @@ shows examples of how to handle errors within a coroutine:

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-query.cpp'><code>c++now-query.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_query.cpp'><code>cppnow_query.cpp</code></a>
<a href='https://godbolt.org/z/dPboEeqfv'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo passing a custom environment into a <code>task</code>
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-query.cpp'><code>c++now-query.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_query.cpp'><code>cppnow_query.cpp</code></a>
shows how to define and use a custom environment element.

1. The coroutine `with_env` uses a simple environment named `context` which just defines a custom query for `get_value`
Expand All @@ -157,13 +157,13 @@ shows how to define and use a custom environment element.

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-result-types.cpp'><code>c++now-result-types.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_result_types.cpp'><code>cppnow_result_types.cpp</code></a>
<a href='https://godbolt.org/z/aWfc8T8he'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo the result type of <code>co_await</code> expressions.
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-result-types.cpp'><code>c++now-result-types.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_result_types.cpp'><code>cppnow_result_types.cpp</code></a>
shows the result types of successful senders using variatons of `just`:

- `co_await just()` doesn't produce a value, i.e., the type of the expression is `void`.
Expand All @@ -174,13 +174,13 @@ shows the result types of successful senders using variatons of `just`:

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-return.cpp'><code>c++now-return.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_return.cpp'><code>cppnow_return.cpp</code></a>
<a href='https://godbolt.org/z/f5YE5W4Ta'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
shows the different normal values returned
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-return.cpp'><code>c++now-return.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_return.cpp'><code>cppnow_return.cpp</code></a>
shows various ways of returning normally (without an error) for a `task`. Some of the coroutines are set up to produce
specific error results although none of them are actually use:

Expand All @@ -193,13 +193,13 @@ specific error results although none of them are actually use:

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-stop_token.cpp'><code>c++now-stop_token.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_stop_token.cpp'><code>cppnow_stop_token.cpp</code></a>
<a href='https://godbolt.org/z/TxYe3jEs7'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo how to get and use a stop token in a `task`
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-stop_token.cpp'><code>c++now-stop_token.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_stop_token.cpp'><code>cppnow_stop_token.cpp</code></a>
shows how to get a stop token in side a `task` and how to use it to cancel active work. It doesn't actually complete
with a `set_stopped()` but completes with `set_value()`.

Expand All @@ -212,13 +212,13 @@ with a `set_stopped()` but completes with `set_value()`.

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-with_error.cpp'><code>c++now-with_error.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_with_error.cpp'><code>cppnow_with_error.cpp</code></a>
<a href='https://godbolt.org/z/6oqox6zf8'><img src='https://raw.githubusercontent.com/bemanproject/task/refs/heads/main/docs/compiler-explorer.ico' width='15' height='15'/></a>:
demo exiting a <code>task</code> with an error
</summary>

The example
<a href='https://github.com/bemanproject/task/blob/main/examples/c%2B%2Bnow-with_error.cpp'><code>c++now-with_error.cpp</code></a>
<a href='https://github.com/bemanproject/task/blob/main/examples/cppnow_with_error.cpp'><code>cppnow_with_error.cpp</code></a>
shows how a coroutine can be exited reporting an error without throwing an exception. To do so, the coroutine
uses `co_yield with_error(e)`. By default the `task` only declares `set_error_t(exception_ptr)`. To return
other errors, an environment declaring a suitable `set_error_t(E)` completion using the `error_types` alias is used.
Expand All @@ -228,19 +228,19 @@ other errors, an environment declaring a suitable `set_error_t(E)` completion us

<details>
<summary>
<a href='https://github.com/bemanproject/task/blob/remove-net-and-improve-docs/examples/demo-thread_loop.hpp'><code>demo::thread_loop</code> is a <code>run_loop</code> whose <code>run()</code> is called from a <code>std::thread</code>.
<a href='https://github.com/bemanproject/task/blob/remove-net-and-improve-docs/examples/demo_thread_loop.hpp'><code>demo::thread_loop</code> is a <code>run_loop</code> whose <code>run()</code> is called from a <code>std::thread</code>.
</summary>

Technically [`demo::thread_loop`](../examples/demo-thread_loop.hpp)
Technically [`demo::thread_loop`](../examples/demo_thread_loop.hpp)
is a class `public`ly derived from `execution::run_loop` which is
also owning a `std::thread`. The `std::thread` is constructed with
a function object calling `run()` on the
[`demo::thread_loop`](../examples/demo-thread_loop.hpp) object.
[`demo::thread_loop`](../examples/demo_thread_loop.hpp) object.
Destroying the object calls `finish()` and then `join()`s the
`std::thread`: the destructor will block until the `execution::run_loop`'s
`run()` returns.

The important bit is that work executed on the
[`demo::thread_loop`](../examples/demo-thread_loop.hpp)'s `scheduler`
[`demo::thread_loop`](../examples/demo_thread_loop.hpp)'s `scheduler`
will be executed on a corresponding `std::thread`.
</details>
50 changes: 25 additions & 25 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,52 @@ if(PROJECT_IS_TOP_LEVEL)
enable_testing()
endif()

set(TODO tls-scheduler into_optional issue-start-reschedules loop)
set(TODO tls_scheduler into_optional issue_start_reschedules loop)

set(ALL_EXAMPLES
task_scheduler
rvalue-task
rvalue_task
customize
issue-symmetric-transfer
issue_symmetric_transfer
container
)

if(NOT MSVC)
list(
APPEND ALL_EXAMPLES
task-sender
alloc-1
alloc-2
c++now-allocator
c++now-cancel
c++now-errors
task_sender
alloc_1
alloc_2
cppnow_allocator
cppnow_cancel
cppnow_errors
alloc
affinity
odd-return
dangling-references
aggregate-return
issue-affine_on
c++now-affinity
c++now-basic
# FIXME: c++now-query
c++now-result-types
c++now-return
# FIXME: c++now-stop_token
c++now-with_error
co_await-result
co_await-task
odd_return
dangling_references
aggregate_return
issue_affine
cppnow_affinity
cppnow_basic
# FIXME: cppnow_query
cppnow_result_types
cppnow_return
# FIXME: cppnow_stop_token
cppnow_with_error
co_await_result
co_await_task
error
escaped-exception
escaped_exception
friendly
hello
issue-frame-allocator
issue_frame_allocator
# FIXME: query
result_example
# FIXME: stop
)
endif()

set(xALL_EXAMPLES issue-symmetric-transfer)
set(xALL_EXAMPLES issue_symmetric_transfer)
set(xALL_EXAMPLES customize)

message(STATUS "Examples to be built: ${ALL_EXAMPLES}")
Expand Down
2 changes: 1 addition & 1 deletion examples/affinity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <beman/execution/execution.hpp>
#include <beman/task/task.hpp>
#include "demo-thread_loop.hpp"
#include "demo_thread_loop.hpp"
#include <iostream>
#include <cassert>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/aggregate-return.cpp -*-C++-*-
// examples/aggregate_return.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/execution/execution.hpp>
Expand Down
2 changes: 1 addition & 1 deletion examples/alloc-1.cpp → examples/alloc_1.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/alloc-1.cpp -*-C++-*-
// examples/alloc_1.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/execution/task.hpp>
Expand Down
2 changes: 1 addition & 1 deletion examples/alloc-2.cpp → examples/alloc_2.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/alloc-1.cpp -*-C++-*-
// examples/alloc_1.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/execution/task.hpp>
Expand Down
5 changes: 2 additions & 3 deletions examples/async-lock.cpp → examples/async_lock.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/async-lock -*-C++-*-
// examples/async_lock -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <iostream>
Expand Down Expand Up @@ -103,8 +103,7 @@ int main(int ac, char* av[]) {
}};

if (1 < ac && av[1] == std::string_view("run-it")) {
ex::sync_wait(
ex::detail::write_env(work(q), ex::detail::make_env(ex::get_scheduler, ex::inline_scheduler{})));
ex::sync_wait(ex::write_env(work(q), ex::detail::make_env(ex::get_scheduler, ex::inline_scheduler{})));
} else {
ex::sync_wait(work(q));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/co_await-result.cpp -*-C++-*-
// examples/co_await_result.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/task/task.hpp>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/co_await-task.cpp -*-C++-*-
// examples/co_await_task.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/execution/task.hpp>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// examples/c++now-affinity.cpp -*-C++-*-
// examples/cppnow_affinity.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/task/task.hpp>
#include <beman/execution/execution.hpp>
#include <beman/execution/stop_token.hpp>
#include "demo-thread_loop.hpp"
#include "demo_thread_loop.hpp"
#include <condition_variable>
#include <iostream>
#include <mutex>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/c++now-alloctor.cpp -*-C++-*-
// examples/cppnow_alloctor.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/task/task.hpp>
Expand Down
2 changes: 1 addition & 1 deletion examples/c++now-basic.cpp → examples/cppnow_basic.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// examples/c++now-basic.cpp -*-C++-*-
// examples/cppnow_basic.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/task/task.hpp>
Expand Down
Loading
Loading