最終更新日時: 2026年06月09日 16時03分31秒 (JST)
yoh が更新

履歴 編集

function
<execution>

# std::execution::task_scheduler::schedule(C++26)

    see below schedule();

## 概要

保持中SchedulerのスケジュールSenderを返す。

## 戻り値

その型が`sender`のモデルであり、下記を満たす右辺値`ts-sndr`。

- `get_completion_scheduler<set_value_t>(get_env(ts-sndr))`が`*this`と等しい。
- `get_completion_domain<set_value_t>(get_env(ts-sndr))`が`ts-domain()`と等価な式である。
- Receiver `rcvr`が`ts-sndr`に接続され、結果のOpearation Stateが開始されるとき、次の値で`sch_->schedule(r, s)`を呼び出す。
  - `r`は基底クラス`parallel_scheduler_replacement::receiver_proxy`を持つ`rcvr`のプロキシであり、かつ
  - `s`は`r`に対する事前確保バックエンドストレージである。
- 任意の型`E`に対して、`unstoppable_token<stop_token_of_t<E>>`が`true`のとき、`completion_signatures_of_t<decltype(ts-sndr)>, E>`は`completion_signatures<set_value_t()>`を表す。そうでなければ、`completion_signatures<set_value_t(), set_stopped_t()>`を表す。

## 説明専用エンティティ

### 式`WARP-RCVR`

`receiver_proxy`から派生した型の左辺値`r`に対して、`WARP-RCVR(r)`を`receiver`のモデルであり、その完了ハンドラが`r`の対応する完了ハンドラを呼び出すような型のオブジェクトとする。

### クラステンプレート`backend-for`

    namespace std::execution {
      template<scheduler Sch>
      class task_scheduler::backend-for
        : public parallel_scheduler_replacement::parallel_scheduler_backend {  // exposition only
      public:
        explicit backend-for(Sch sch) : sched_(std::move(sch)) {}

        void schedule(receiver_proxy& r, span<byte> s) noexcept override;
        void schedule_bulk_chunked(size_t shape, bulk_item_receiver_proxy& r,
                                   span<byte> s) noexcept override;
        void schedule_bulk_unchunked(size_t shape, bulk_item_receiver_proxy& r,
                                     span<byte> s) noexcept override;

      private:
        Sch sched_;
      };
    }

`env`を部分式のパックとしたとき、値完了シグネチャ`set_value_t()`のみを持ち式`get_completion_scheduler<set_value_t>(get_env(just-sndr-like), env...)`が`get_completion_scheduler<set_value_t>(sched_, env...)`と等価な式であるような`Sender`を`just-sndr-like`とする。

    void schedule(receiver_proxy& r, span<byte> s) noexcept override;

- 効果 : `connect(schedule(sched_), WRAP-RCVR(r))`でOperation State `os`を構築し、`start(os)`を呼び出す。

    void schedule_bulk_chunked(size_t shape, bulk_item_receiver_proxy& r,
                               span<byte> s) noexcept override;

- 効果 : 説明用の`chunk_size`を`shape`以下の整数、`chunk_num`を`(shape + chunk_size - 1) / chunk_size`、`m`を`(i + 1) * chunk_size`と`shape`のうち小さい方として、整数`i`に対して`fn(i)`が`r.execute(i * chunk_sie, m)`を呼び出す関数オブジェクト`fn`とする。下記の式によってOperation State `os`を構築し、`start(os)`を呼び出す。

      connect(bulk(just-sndr-like, par, num_chunks, fn), WRAP-RCVR(r))

    void schedule_bulk_unchunked(size_t shape, bulk_item_receiver_proxy& r,
                                 span<byte> s) noexcept override;

- 効果 : 整数`i`に対して`fn(i)`が`r.execute(i, i + 1)`を呼び出す関数オブジェクト`fn`とする。下記の式によってOperation State `os`を構築し、`start(os)`を呼び出す。

      connect(bulk(just-sndr-like, par, shape, fn), WRAP-RCVR(r))

### クラス`ts-domain`

    namespace std::execution {
      class task_scheduler::ts-domain : public default_domain {  // exposition only
      public:
        template<class BulkSndr, class Env>  // exposition only
        static constexpr auto transform_sender(set_value_t, BulkSndr&& bulk_sndr, const Env& env)
          noexcept(see below);
      };
    }

    template<class BulkSndr, class Env>
    static constexpr auto transform_sender(BulkSndr&& bulk_sndr, const Env& env)
      noexcept(is_nothrow_constructible_v<decay_t<BulkSndr>, BulkSndr>);

- テンプレートパラメータ制約 :
  - `sender_in<BulkSndr, Env>`が`true`
  - 式`auto(std::forward<BulkSndr>(bulk_sndr))`が適格
  - 下記のいずれかが`true`
    - `sender-for<BulkSndr, bulk_chunked_t>`
    - `sender-for<BulkSndr, bulk_unchunked_t>`

- 効果 : 下記と等価

      auto& [_, data, child] = bulk_sndr;
      auto& [_, shape, fn] = data;
      auto sch = call-with-default(get_completion_scheduler<set_value_t>,
                                   not-a-scheduler(), get_env(child), FWD-ENV(env));
      return e;

  ここで、`sch`の型が`task_scheduler`ではないとき、`e`は`not-a-sender()`とする。そうでなければ、Receiver `rvcr`と接続(connect)され結果のOperation Stateが開始(start)されたとき、`child`が未規定のReceiver`R`と接続されて開始する`sender`のモデルである型の右辺値とする。

  `child`がエラー完了もしくは停止完了するとき、完了操作は変更されずに`rcvr`に転送される。そうでなければ、値完了結果からdecayコピーされたオブジェクトを指す左辺値式のパック`args`として、

  - `bulk_sndr`が`bulk_chunked(child, policy, shape, fn)`と等価な式またはそのコピーの評価の結果であるとき、`r`を呼び出し可能オブジェクト`fn`と引数`args`を持つ`rcvr`に対するbulk chunkedプロキシ、`s`を`r`の事前確保バックエンドストレージとして、`sch_->schedule_bulk_chunked(shape, r, s)`が呼び出される。
  - そうでなければ、`r`を呼び出し可能オブジェクト`fn`と引数`args`を持つ`rcvr`に対するbulk unchunkedプロキシ、`s`を`r`の事前確保バックエンドストレージとして、`sch_->schedule_bulk_unchunked(shape, r, s)`が呼び出される。

## バージョン

### 言語

- C++26

### 処理系

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

## 関連項目

- `execition::schedule`
- `execition::bulk_chunked`
- `execition::bulk_unchunked`

## 参照

- P3552R3 Add a Coroutine Task Type
- P3941R4 Scheduler Affinity
- P3927R2 `task_scheduler` support for parallel `bulk` execution