Skip to content

Commit 14088f2

Browse files
committed
execution: P3941R4対応(#1648)
1 parent a664e2e commit 14088f2

18 files changed

Lines changed: 191 additions & 163 deletions

reference/execution/execution.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace std::execution {
4141
| [`stop_token_of_t`](stop_token_of_t.md) | 指定型から停止トークン型を取得 (alias template) | C++26 |
4242
| [`execution::get_domain`](execution/get_domain.md) | 実行ドメイン取得のクエリオブジェクト (customization point object) | C++26 |
4343
| [`execution::get_scheduler`](execution/get_scheduler.md) | Scheduler取得のクエリオブジェクト (customization point object) | C++26 |
44+
| [`execution::get_start_scheduler`](execution/get_start_scheduler.md) | 開始Scheduler取得のクエリオブジェクト (customization point object) | C++26 |
4445
| [`execution::get_delegation_scheduler`](execution/get_delegation_scheduler.md) | 委任Scheduler取得のクエリオブジェクト (customization point object) | C++26 |
4546
| [`execution::forward_progress_guarantee`](execution/forward_progress_guarantee.md) | 前方進行保証 (enum) | C++26 |
4647
| [`execution::get_forward_progress_guarantee`](execution/get_forward_progress_guarantee.md) | 前方進行保証取得のクエリオブジェクト (customization point object) | C++26 |
@@ -166,7 +167,6 @@ Senderコンシューマは名前空間 `std::this_thread` および名前空間
166167
| [`execution::inline_scheduler`](execution/inline_scheduler.md) | インラインScheduler (class) | C++26 |
167168
| [`execution::task_scheduler`](execution/task_scheduler.md) | 任意Scheduler型を保持するScheduler (class) | C++26 |
168169
| [`execution::with_error`](execution/with_error.md) | タスクコルーチンからのエラー完了 (class template) | C++26 |
169-
| [`execution::change_coroutine_scheduler`](execution/change_coroutine_scheduler.md) | タスクコルーチンのScheduler変更 (class template) | C++26 |
170170
| [`execution::task`](execution/task.md) | タスクコルーチン戻り値型 (class template) | C++26 |
171171
172172
### 実行スコープユーティリティ
@@ -206,3 +206,4 @@ Senderコンシューマは名前空間 `std::this_thread` および名前空間
206206
- [P3815R1 Add `scope_association` concept to P3149](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3815r1.html)
207207
- [P3986R1 A Wording Strategy for Inlinable Receivers](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3986r1.pdf)
208208
- [P3826R5 Fix Sender Algorithm Customization](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html)
209+
- [P3941R4 Scheduler Affinity](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html)

reference/execution/execution/affine_on.md

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,64 @@ namespace std::execution {
1313
* unspecified[italic]
1414
1515
## 概要
16-
`affine_on`は、指定[Scheduler](scheduler.md)上で完了させるSenderアダプタである。
16+
`affine_on`は、[Receiver](receiver.md)の[Scheduler](scheduler.md)上で完了させるSenderアダプタである。
1717
アダプト対象Senderが正しいScheduler上で完了すると判断できるとき、アルゴリズムはスケジューリング操作を回避できる。
1818
1919
`affine_on`は[パイプ可能Senderアダプタオブジェクト](sender_adaptor_closure.md)であり、パイプライン記法をサポートする。
2020
2121
2222
## 効果
23-
説明用の式`sch`と`sndr`に対して、`decltype((sch))`が[`scheduler`](scheduler.md)を満たさない、もしくは`decltype((sndr))`が[`sender`](sender.md)を満たさないとき、呼び出し式`affine_on(sndr, sch)`は不適格となる。
23+
説明用の式`sndr`に対して、`decltype((sndr))`が[`sender`](sender.md)を満たさないとき、呼び出し式`affine_on(sndr)`は不適格となる。
2424
25-
そうでなければ、呼び出し式`affine_on(sndr, sch)`は下記と等価。
25+
そうでなければ、呼び出し式`affine_on(sndr)`は下記と等価。
2626
2727
```cpp
28-
make-sender(affine_on, sch, sndr)
28+
make-sender(affine_on, env<>(), sndr)
2929
```
3030
* make-sender[link make-sender.md]
31+
* env<>[link env.md]
32+
33+
34+
### Senderアルゴリズムタグ `affine_on`
35+
型が[`scheduler`](scheduler.md)のモデルである部分式`sch`に対して、説明用の式`UNSTOPPABLE-SCHEDULER(sch)`を、その型が[`scheduler`](scheduler.md)のモデルである式`e`とする。
36+
37+
-[`schedule`](schedule.md)`(e)`[`unstoppable`](unstoppable.md)`(`[`schedule`](schedule.md)`(sch))`と等価な式。
38+
- 任意の[クエリオブジェクト](../queryable.md)`q`と部分式のパック`args...`に対して、式`e.query(q, args...)``sch.query(q, args...)`と等価な式。
39+
-`e == UNSTOPPABLE-SCHEDULER(other)``sch == other`と等価な式。
40+
41+
説明用の式`sndr``ev`に対して、[`sender-for`](sender-for.md)`<decltype((sndr)), affine_on_t> == false`のとき、式`affine_on.transform_sender(sndr, ev)`は不適格となる。
42+
43+
そうでなければ、式`affine_on.transform_sender(sndr, ev)`は下記と等価。
44+
45+
```cpp
46+
auto& [_, _, child] = sndr;
47+
if constexpr (requires { std::forward_like<Sndr>(child).affine_on(); }) {
48+
return std::forward_like<Sndr>(child).affine_on();
49+
} else {
50+
return continues_on(std::forward_like<Sndr>(child),
51+
UNSTOPPABLE-SCHEDULER(get_start_scheduler(ev)));
52+
}
53+
```
54+
* continues_on[link continues_on.md]
55+
* get_start_scheduler[link get_start_scheduler.md]
3156

3257

3358
## カスタマイゼーションポイント
3459
[Receiver](receiver.md)接続時に、関連付けられた実行ドメインに対して[`execution::transform_sender`](transform_sender.md)経由でSender変換が行われる。
3560
[デフォルト実行ドメイン](default_domain.md)では無変換。
3661

37-
説明用の式`out_sndr`を`affine_on(sndr, sch)`の戻り値[Sender](sender.md)とし、型`OutSndr`を`decltype((out_sndr))`とする。式`out_rcvr`を[`sender_in`](sender_in.md)`<OutSndr, Env> == true`となる[環境](../queryable.md)`Env`に関連付けられた[Receiver](receiver.md)とする。`out_sndr`と`out_rcvr`との[接続(connect)](connect.md)結果[Operation State](operation_state.md)への左辺値参照を`op`としたとき、
62+
説明用の式`out_sndr`を`affine_on(sndr)`の戻り値[Sender](sender.md)とし、型`OutSndr`を`decltype((out_sndr))`とする。式`out_rcvr`を[環境](../queryable.md)`Env`に関連付けられた[Receiver](receiver.md)とする。[`get_start_scheduler`](get_start_scheduler.md)`(`[`get_env`](get_env.md)`(out_rcvr))`が不適格もしくは[`infallible-scheduler](infallible-scheduler.md)`<Env>`を満たさないとき、式[`get_completion_signatures`](get_completion_signatures.md)`<OutSndr, Env>()`の評価は例外で終了する。`out_sndr`と`out_rcvr`との[接続(connect)](connect.md)結果[Operation State](operation_state.md)への左辺値参照を`op`としたとき、
3863

3964
- 呼び出し[`start`](start.md)`(op)`は、現在の実行エージェント上で入力[Sender](sender.md)`sndr`を開始し、[Scheduler](scheduler.md)`sch`に関連付けられた実行リソースに属する実行エージェント上で`out_rcvr`の完了操作が実行される。
4065
- 現在の実行リソースが`sch`に関連付けられた実行リソースと同一のとき、[`start`](start.md)`(op)`の完了よりも前に`out_rcvr`の完了操作が呼ばれる可能性がある。
41-
- `sch`上でのスケジューリングが失敗した場合、未規定の実行エージェント上で`out_rcvr`の[エラー完了](set_error.md)が行われるべき。
4266

4367

4468
## 備考
45-
`affine_on`アルゴリズムの動作は[`continues_on`](continues_on.md)と等価だが、処理系は不要なスケジューリング操作を省略(最適化)する可能性がある。
46-
4769
`affine_on`は[タスクコルーチン](task.md)のScheduler Affinity実現に用いられる。
4870
詳細仕様は[`task::promise::await_transform`](task/promise_type/await_transform.md)を参照のこと。
4971

72+
開始された[Scheduler](scheduler.md)上で再開(resume)されると分かっている[Sender](sender.md)に対して、処理系(標準ライブラリ実装)は`affine_on`メンバ関数を提供すべきである。そのようなSenderの例として、[`just`](just.md), [`just_error`](just_error.md), [`just_stopped`](just_stopped.md), [`read_env`](read_env.md), [`write_env`](write_env.md)等がある。
73+
5074

5175
## バージョン
5276
### 言語
@@ -66,3 +90,4 @@ make-sender(affine_on, sch, sndr)
6690
## 参照
6791
- [P3552R3 Add a Coroutine Task Type](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3552r3.html)
6892
- [P3826R5 Fix Sender Algorithm Customization](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html)
93+
- [P3941R4 Scheduler Affinity](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html)

reference/execution/execution/as_awaitable.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Promise型`p`をもつコルーチンにおいて、Await式`co_await as_awaitab
1919
2020
- 式`expr.as_awaitable(p)`が有効ならば、同式が返すAwaitableオブジェクトに対してAwait式を実行する。
2121
- `expr`が[Sender型](sender.md)かつ[`get_await_completion_adaptor`](get_await_completion_adaptor.md)問い合わせに対応する場合、同問い合わせが返すSenderアダプタを`expr`に適用した結果を`adapted-expr`とする。
22-
2322
- `expr`(または上記ステップの`adapted-expr`)が[単一の値を送信するSender](single-sender.md)であり、Promise型が停止完了ハンドラを定義するならば、下記動作を行う。
2423
- Senderを[接続(connect)](connect.md)し、結果[Operation State](operation_state.md)をAwaitableオブジェクトに格納する。
2524
- コルーチンを中断し、Operation Stateを[開始(start)](start.md)する。
@@ -37,13 +36,29 @@ Promise型`p`をもつコルーチンにおいて、Await式`co_await as_awaitab
3736
3837
- 適格であるならば、式`expr.as_awaitable(p)`
3938
- 適格要件 : 同式の型を`A`としたとき、[`is-awaitable`](../is-awaitable.md)`<A, Promise> == true`であるべき。
39+
- そうではなく、下記の式が適格であり[`sender_in`](sender_in.md)`<Expr,` [`env_of_t`](env_of_t.md)`<Promise>>`が`true`、かつ[`single-sender-value-type`](single-sender-value-type.md)`<Expr,` [`env_of_t`](env_of_t.md)`<Promise>>`が適格ならば、`p`が1回だけ評価されることを除いて下記と等価。
40+
```cpp
41+
adapt-for-await-completion(transform_sender(expr, get_env(p))).as_awaitable(p)
42+
```
43+
* transform_sender[link transform_sender.md]
44+
* get_env[link get_env.md]
4045
- そうではなく、`decltype(`[`GET-AWAITER`](../is-awaitable.md)`(expr))`が[`is-awaiter`](../is-awaitable.md)`<Promise>`を満たすならば、式`(void(p), expr)`
41-
- そうではなく、説明用の式`adapted-expr`を`expr`が1回だけ評価されることを除いて[`get_await_completion_adaptor`](get_await_completion_adaptor.md)`(`[`get_env`](get_env.md)`(expr))(expr)`としたとき、`has-queryable-await-completion-adaptor<Expr>`と`awaitable-sender<decltype((adapted-expr)), Promise>`が共に満たされるならば、式`sender-awaitable{adapted-expr, p}`
42-
- そうではなく、`awaitable-sender<Expr, Promise>`ならば、式`sender-awaitable{expr, p}`
46+
- そうではなく、下記の式が適格であり[`sender_in`](sender_in.md)`<Expr,` [`env_of_t`](env_of_t.md)`<Promise>>`が`true`、かつ[`single-sender-value-type`](single-sender-value-type.md)`<Expr,` [`env_of_t`](env_of_t.md)`<Promise>>`が適格ならば、`p`が1回だけ評価されることを除いて下記と等価。
47+
```cpp
48+
sender-awaitable{adapt-for-await-completion(transform_sender(expr, get_env(p))), p}
49+
```
50+
* transform_sender[link transform_sender.md]
51+
* get_env[link get_env.md]
4352
- そうでなければ、式`(void(p), expr)`
4453
4554
4655
## 説明専用エンティティ
56+
### 式`adapt-for-await-completion`
57+
式`adapt-for-await-completion(s)`は下記と等しい。
58+
59+
- 式が適格であるならば、`s`が1回だけ評価されることを除いて、[`get_await_completion_adaptor`](get_await_completion_adaptor.md)`(`[`get_env`](get_env.md)`(s))(s)`
60+
- そうでなければ、`s`
61+
4762
### コンセプト`awaitable-sender`
4863
```cpp
4964
namespace std::execution {
@@ -246,3 +261,4 @@ value-type await_resume();
246261
- [LWG4360 `awaitable-sender` concept should qualify use of `awaitable-receiver` type](https://cplusplus.github.io/LWG/issue4360)
247262
- [LWG4133 `awaitable-receiver`'s members are potentially throwing](https://cplusplus.github.io/LWG/issue4133)
248263
- [LWG4361 `awaitable-receiver::set_value` should use Mandates instead of constraints](https://cplusplus.github.io/LWG/issue4361)
264+
- [P3941R4 Scheduler Affinity](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html)

reference/execution/execution/change_coroutine_scheduler.md

Lines changed: 0 additions & 104 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# get_start_scheduler
2+
* execution[meta header]
3+
* cpo[meta id-type]
4+
* std::execution[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std::execution {
9+
struct get_start_scheduler { unspecified };
10+
inline constexpr get_start_scheduler_t get_start_scheduler{};
11+
}
12+
```
13+
* unspecified[italic]
14+
15+
## 概要
16+
`get_start_scheduler`は、操作を[開始(start)](start.md)予定もしくは開始された[Scheduler](scheduler.md)を取得する[クエリオブジェクト](../queryable.md)である。
17+
18+
コア定数式[`forwarding_query`](../forwarding_query.md)`(get_start_scheduler)`は`true`値を返す。
19+
20+
21+
## 効果
22+
部分式`env`に対して、呼び出し式`get_start_scheduler(env)`は[`MANDATE-NOTHROW`](MANDATE-NOTHROW.md)`(`[`AS-CONST`](AS-CONST.md)`(env).query(get_start_scheduler))`と等価な式。
23+
24+
上記の式が適格なとき、その型は[`scheduler`](scheduler.md)を満たすこと。
25+
26+
27+
## 例外
28+
投げない
29+
30+
31+
## カスタマイゼーションポイント
32+
const修飾[クエリ可能オブジェクト](../queryable.md)`cenv`に対して式`cenv.query(get_start_scheduler)`が呼び出される。
33+
このとき、`noexcept(cenv.query(get_start_scheduler)) == true`であること。
34+
35+
[`sender_to`](sender_to.md)`<decltype((sndr)), decltype((rcvr))>`が`true`かつ式`get_start_scheduler(`[`get_env`](get_env.md)`(rcvr))`が適格となる式`sndr`と`rcvr`に対して、[`connect`](connect.md)`(sndr, rcvr)`の呼び出し結果である[Operation State](operation_state.md)が[開始(start)](start.md)される場合、[Scheduler](scheduler.md)`get_start_scheduler(`[`get_env`](get_env.md)`(rcvr))`に関連付けられた実行エージェント上で開始されなければならない。
36+
37+
38+
## バージョン
39+
### 言語
40+
- C++26
41+
42+
### 処理系
43+
- [Clang](/implementation.md#clang): ??
44+
- [GCC](/implementation.md#gcc): ??
45+
- [ICC](/implementation.md#icc): ??
46+
- [Visual C++](/implementation.md#visual_cpp): ??
47+
48+
49+
## 関連項目
50+
- [`execution::scheduler`](scheduler.md)
51+
52+
53+
## 参照
54+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)
55+
- [P3826R5 Fix Sender Algorithm Customization](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3826r5.html)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# infallible-scheduler
2+
* [meta exposition-only]
3+
* execution[meta header]
4+
* concept[meta id-type]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
template <class Sch, class Env>
9+
concept infallible-scheduler =
10+
scheduler<Sch> &&
11+
(same_as<completion_signatures<set_value_t()>,
12+
completion_signatures_of_t<decltype(schedule(declval<Sch>())), Env>> ||
13+
(!unstoppable_token<stop_token_of_t<Env>> &&
14+
(same_as<completion_signatures<set_value_t(), set_stopped_t()>,
15+
completion_signatures_of_t<decltype(schedule(declval<Sch>())), Env>> ||
16+
same_as<completion_signatures<set_stopped_t(), set_value_t()>,
17+
completion_signatures_of_t<decltype(schedule(declval<Sch>())), Env>>)));
18+
```
19+
* scheduler[link scheduler.md]
20+
* schedule[link schedule.md]
21+
* completion_signatures[link completion_signatures.md]
22+
* completion_signatures_of_t[link completion_signatures_of_t.md]
23+
* set_value_t[link set_value.md]
24+
* set_stopped_t[link set_stopped.md]
25+
* stop_token_of_t[link ../stop_token_of_t.md]
26+
* unstoppable_token[link /reference/stop_token/unstoppable_token.md]
27+
28+
## 概要
29+
`infallible-scheduler`は、[`schedule`](schedule.md)による非同期操作が停止要求されない限り[`set_value`](set_value.md)によってのみ完了する[`Scheduler`](scheduler.md)型の要件を定義する説明専用のコンセプトである。
30+
31+
32+
## バージョン
33+
### 言語
34+
- C++26
35+
36+
37+
## 関連項目
38+
- [`execution::scheduler`](scheduler.md)
39+
40+
41+
## 参照
42+
- [P3941R4 Scheduler Affinity](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3941r4.html)

0 commit comments

Comments
 (0)