最終更新日時: 2026年06月07日 18時28分55秒 (JST)
yoh が更新

履歴 編集

customization point object
<execution>

# std::execution::affine(C++26)

    namespace std::execution {
      struct affine_t { unspecified };
      inline constexpr affine_t affine{};
    }

## 概要

`affine`は、ReceiverのScheduler上で完了させるSenderアダプタである。 アダプト対象Senderが正しいScheduler上で完了すると判断できるとき、アルゴリズムはスケジューリング操作を回避できる。

`affine`はパイプ可能Senderアダプタオブジェクトであり、パイプライン記法をサポートする。

## 効果

説明用の式`sndr`に対して、`decltype((sndr))`が`sender`を満たさないとき、呼び出し式`affine(sndr)`は不適格となる。

そうでなければ、呼び出し式`affine(sndr)`は下記と等価。

    make-sender(affine, env<>(), sndr)

### Senderアルゴリズムタグ `affine`

型が`scheduler`のモデルである部分式`sch`に対して、説明用の式`UNSTOPPABLE-SCHEDULER(sch)`を、その型が`scheduler`のモデルである式`e`とする。

- 式`schedule(e)`は`unstoppable(schedule(sch))`と等価な式。
- 任意のクエリオブジェクト `q`と部分式のパック`args...`に対して、式`e.query(q, args...)`は`sch.query(q, args...)`と等価な式。
- 式`e == UNSTOPPABLE-SCHEDULER(other)`は`sch == other`と等価な式。

説明用の式`sndr`と`ev`に対して、`sender-for<decltype((sndr)), affine_t> == false`のとき、式`affine.transform_sender(sndr, ev)`は不適格となる。

そうでなければ、式`affine.transform_sender(sndr, ev)`は下記と等価。

    auto& [_, _, child] = sndr;
    if constexpr (requires { std::forward_like<Sndr>(child).affine(); }) {
      return std::forward_like<Sndr>(child).affine();
    } else {
      return continues_on(std::forward_like<Sndr>(child),
                          UNSTOPPABLE-SCHEDULER(get_start_scheduler(ev)));
    }

## カスタマイゼーションポイント

Receiver接続時に、関連付けられた実行ドメインに対して`execution::transform_sender`経由でSender変換が行われる。 デフォルト実行ドメインでは無変換。

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

- 呼び出し`start(op)`は、現在の実行エージェント上で入力Sender `sndr`を開始し、Scheduler `sch`に関連付けられた実行リソースに属する実行エージェント上で`out_rcvr`の完了操作が実行される。
- 現在の実行リソースが`sch`に関連付けられた実行リソースと同一のとき、`start(op)`の完了よりも前に`out_rcvr`の完了操作が呼ばれる可能性がある。

## 備考

`affine`はタスクコルーチンのScheduler Affinity実現に用いられる。 詳細仕様は`task::promise::await_transform`を参照のこと。

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

## バージョン

### 言語

- C++26

### 処理系

- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??

## 関連項目

- `execution::task`

## 参照

- P3552R3 Add a Coroutine Task Type
- P3826R5 Fix Sender Algorithm Customization
- P3941R4 Scheduler Affinity
- P4151R1 Rename `affine_on`