最終更新日時(UTC):
が更新

履歴 編集

customization point object
<execution>

std::execution::bulk(C++26)

namespace std::execution {
  struct bulk_t { unspecified };
  inline constexpr bulk_t bulk{};
}

概要

bulkは、インデクス空間の各インデクスに対してタスクを反復実行するSenderアダプタである。

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

効果

説明用の式sndr, shape, fに対して、型Shapedecltype(auto(shape))とする。下記いずれかの条件をみたすとき、呼び出し式bulk(sndr, shape, f)不適格となる。

  • decltype((sndr))senderを満たさない、もしくは
  • Shapeintegralを満たさない、もしくは
  • decltype((f))movable-valueを満たさないとき。

そうでなければ、呼び出し式bulk(sndr, shape, f)sndrが1回だけ評価されることを除いて、下記と等価。

Senderアルゴリズムタグ bulk

Senderアルゴリズム動作説明用のクラステンプレートimpls-forに対して、下記の特殊化が定義される。

namespace std::execution {
  template<>
  struct impls-for<bulk_t> : default-impls {
    static constexpr auto complete = see below;
  };
}

impls-for<bulk_t>::completeメンバは、下記ラムダ式と等価な関数呼び出し可能なオブジェクトで初期化される。

[]<class Index, class State, class Rcvr, class Tag, class... Args>
  (Index, State& state, Rcvr& rcvr, Tag, Args&&... args) noexcept -> void requires see below {
    if constexpr (same_as<Tag, set_value_t>) {
      auto& [shape, f] = state;
      constexpr bool nothrow = noexcept(f(auto(shape), args...));
      TRY-EVAL(rcvr, [&]() noexcept(nothrow) {
        for (decltype(auto(shape)) i = 0; i < shape; ++i) {
          f(auto(i), args...);
        }
        Tag()(std::move(rcvr), std::forward<Args>(args)...);
      }());
    } else {
      Tag()(std::move(rcvr), std::forward<Args>(args)...);
    }
  }

Tagset_value_t以外の型であるとき、もしくは式f(auto(shape), args...)適格なときに限って、上記ラムダ式のrequires節が満たされる。

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

Senderアルゴリズム構築時およびReceiver接続時に、関連付けられた実行ドメインに対してexecution::transform_sender経由でSender変換が行われる。 デフォルト実行ドメインでは無変換。

説明用の式out_sndrbulk(sndr, shape, f)戻り値Senderとし、式rcvrを式connect(out_sndr, rcvr)適格となるReceiverとする。式connect(out_sndr, rcvr)開始(start)時に下記を満たす非同期操作を生成しない場合、動作は未定義となる。

  • 値完了操作において、パックargsを入力Senderの値完了結果データを参照する左辺値式としたとき、型Shapeの半開区間[0, Shape)における全てのiに対してf(i, args...)を呼び出すこと。
  • sndrにより送信された全ての完了操作を伝搬すること。

備考

非同期実行フレームワークで定義されるデフォルト実行ドメインでは、bulkに指定したタスクfは単一スレッド上で逐次実行される。

#include <print>
#include <execution>
namespace ex = std::execution;

int main()
{
  ex::sender auto sndr =
    ex::just()
    | ex::bulk(3, [](int i) {
        std::println("{}", i);
      });
  std::this_thread::sync_wait(sndr);
}

出力例

0
1
2

バージョン

言語

  • C++26

処理系

参照