|
| 1 | +# basic-operation |
| 2 | +* execution[meta header] |
| 3 | +* class template[meta id-type] |
| 4 | +* std::execution[meta namespace] |
| 5 | +* cpp26[meta cpp] |
| 6 | + |
| 7 | +```cpp |
| 8 | +namespace std::execution { |
| 9 | + template<class Sndr, class Rcvr> |
| 10 | + requires valid-specialization<state-type, Sndr, Rcvr> && |
| 11 | + valid-specialization<connect-all-result, Sndr, Rcvr> |
| 12 | + struct basic-operation : basic-state<Sndr, Rcvr> { // exposition only |
| 13 | + using operation_state_concept = operation_state_t; |
| 14 | + using tag-t = tag_of_t<Sndr>; // exposition only |
| 15 | + |
| 16 | + connect-all-result<Sndr, Rcvr> inner-ops; // exposition only |
| 17 | + |
| 18 | + basic-operation(Sndr&& sndr, Rcvr&& rcvr) noexcept(see below) // exposition only |
| 19 | + : basic-state<Sndr, Rcvr>(std::forward<Sndr>(sndr), std::move(rcvr)), |
| 20 | + inner-ops(connect-all(this, std::forward<Sndr>(sndr), indices-for<Sndr>())) |
| 21 | + {} |
| 22 | + |
| 23 | + void start() & noexcept { |
| 24 | + auto& [...ops] = inner-ops; |
| 25 | + impls-for<tag-t>::start(this->state, this->rcvr, ops...); |
| 26 | + } |
| 27 | + }; |
| 28 | + |
| 29 | + template<class Sndr, class Rcvr> |
| 30 | + struct basic-state { // exposition only |
| 31 | + basic-state(Sndr&& sndr, Rcvr&& rcvr) noexcept(see below) |
| 32 | + : rcvr(std::move(rcvr)) |
| 33 | + , state(impls-for<tag_of_t<Sndr>>::get-state(std::forward<Sndr>(sndr), rcvr)) { } |
| 34 | + |
| 35 | + Rcvr rcvr; // exposition only |
| 36 | + state-type<Sndr, Rcvr> state; // exposition only |
| 37 | + }; |
| 38 | +} |
| 39 | +``` |
| 40 | +* operation_state_t[link operation_state.md] |
| 41 | +* tag_of_t[link tag_of_t.md.nolink] |
| 42 | +* impls-for[link impls-for.md] |
| 43 | +* see below[italic] |
| 44 | + |
| 45 | +## 概要 |
| 46 | +`basic-operation`および`basic-state`は、Senderアルゴリズム動作仕様定義で用いられる説明専用のクラステンプレートである。 |
| 47 | + |
| 48 | +`basic-operation<Sndr, Rcvr>`は[`operation_state`](operation_state.md)のモデルであり、[Senderアルゴリズム](basic-sender.md)と[Recevier](receiver.md)の[接続(connect)](connect.md)結果型として利用される。 |
| 49 | + |
| 50 | +- `rcvr` : 接続先Receiverオブジェクトを保持。Senderアルゴリズム同士を連結する場合は、親Senderアルゴリズム側の[Receiver](receiver.md)が該当する。 |
| 51 | +- `state` : Senderアルゴリズム構築時の引数リストを保持。([`impls-for`](impls-for.md)でカスタマイズ可能) |
| 52 | +- `inner-ops` : 子SenderリストとSenderアルゴリズムとの接続結果[Operation State](operation_state.md)リストを保持。Senderファクトリでは0個、Senderアダプタでは通常1個の子Senderと接続される。 |
| 53 | + |
| 54 | + |
| 55 | +## クラス仕様 |
| 56 | +`basic-operation`コンストラクタ`noexcept`節の式は下記の通り。 |
| 57 | + |
| 58 | +```cpp |
| 59 | +is_nothrow_constructible_v<basic-state<Self, Rcvr>, Self, Rcvr> && |
| 60 | +noexcept(connect-all(this, std::forward<Sndr>(sndr), indices-for<Sndr>())) |
| 61 | +``` |
| 62 | +* is_nothrow_constructible_v[link /reference/type_traits/is_nothrow_constructible.md] |
| 63 | +
|
| 64 | +`basic-state`コンストラクタ`noexcept`節の式は下記の通り。 |
| 65 | +
|
| 66 | +```cpp |
| 67 | +is_nothrow_move_constructible_v<Rcvr> && |
| 68 | +nothrow-callable<decltype(impls-for<tag_of_t<Sndr>>::get-state), Sndr, Rcvr&> && |
| 69 | +(same_as<state-type<Sndr, Rcvr>, get-state-result> || |
| 70 | + is_nothrow_constructible_v<state-type<Sndr, Rcvr>, get-state-result>) |
| 71 | +``` |
| 72 | +* impls-for[link impls-for.md] |
| 73 | +* tag_of_t[link tag_of_t.md.nolink] |
| 74 | +* is_nothrow_move_constructible_v[link /reference/type_traits/is_nothrow_move_constructible.md] |
| 75 | +* is_nothrow_constructible_v[link /reference/type_traits/is_nothrow_constructible.md] |
| 76 | + |
| 77 | +ここで、説明用の型`get-state-result`は下記の通り定義される。 |
| 78 | + |
| 79 | +```cpp |
| 80 | +call-result-t<decltype(impls-for<tag_of_t<Sndr>>::get-state), Sndr, Rcvr&>. |
| 81 | +``` |
| 82 | +* impls-for[link impls-for.md] |
| 83 | +* tag_of_t[link tag_of_t.md.nolink] |
| 84 | + |
| 85 | + |
| 86 | +## 説明専用エンティティ |
| 87 | + |
| 88 | +```cpp |
| 89 | +template<template<class...> class T, class... Args> |
| 90 | +concept valid-specialization = // exposition only |
| 91 | + requires { typename T<Args...>; }; |
| 92 | + |
| 93 | +template<class Sndr, class Rcvr> // exposition only |
| 94 | +using state-type = decay_t<call-result-t< |
| 95 | + decltype(impls-for<tag_of_t<Sndr>>::get-state), Sndr, Rcvr&>>; |
| 96 | + |
| 97 | +constexpr auto connect-all = see below; // exposition only |
| 98 | + |
| 99 | +template<class Sndr, class Rcvr> |
| 100 | +using connect-all-result = call-result-t< // exposition only |
| 101 | + decltype(connect-all), basic-state<Sndr, Rcvr>*, Sndr, indices-for<Sndr>>; |
| 102 | + |
| 103 | +template<class Sndr> |
| 104 | +using indices-for = remove_reference_t<Sndr>::indices-for; // exposition only |
| 105 | +``` |
| 106 | +* impls-for[link impls-for.md] |
| 107 | +* tag_of_t[link tag_of_t.md.nolink] |
| 108 | +* decay_t[link /reference/type_traits/decay.md] |
| 109 | +* remove_reference_t[link /reference/type_traits/remove_reference.md] |
| 110 | +* see below[italic] |
| 111 | +
|
| 112 | +説明専用の定数`connect-all`は、下記ラムダ式と等価な関数呼び出し可能なオブジェクトとして初期化される。 |
| 113 | +
|
| 114 | +- 全ての子Sender`child`とSenderアルゴリズム`sndr`の[Receiver](basic-receiver.md)を[接続(connect)](connec.md)し、結果の[Operation State](operation_state.md)リストを[`product-type`](product-type.md.nolink)型にまとめて返す。 |
| 115 | +
|
| 116 | +```cpp |
| 117 | +[]<class Sndr, class Rcvr, size_t... Is>( |
| 118 | + basic-state<Sndr, Rcvr>* op, Sndr&& sndr, index_sequence<Is...>) noexcept(see below) |
| 119 | + -> decltype(auto) { |
| 120 | + auto& [_, data, ...child] = sndr; |
| 121 | + return product-type{connect( |
| 122 | + std::forward_like<Sndr>(child), |
| 123 | + basic-receiver<Sndr, Rcvr, integral_constant<size_t, Is>>{op})...}; |
| 124 | + } |
| 125 | +``` |
| 126 | +* index_sequence[link /reference/utility/index_sequence.md] |
| 127 | +* product-type[link product-type.md.nolink] |
| 128 | +* connect[link connect.md] |
| 129 | +* basic-receiver[link basic-receiver.md.nolink] |
| 130 | +* integral_constant[link /reference/type_traits/integral_constant.md] |
| 131 | +* see below[italic] |
| 132 | + |
| 133 | +- テンプレートパラメータ制約 : ラムダ式中の`return`文の式が適格であること。 |
| 134 | +- ラムダ式中の`return`文の式が例外送出する可能性がある場合は、`noexcept(false)`となる。そうでなければ、`noexcept(true)`となる。 |
| 135 | + |
| 136 | + |
| 137 | +## バージョン |
| 138 | +### 言語 |
| 139 | +- C++26 |
| 140 | + |
| 141 | + |
| 142 | +## 関連項目 |
| 143 | +- [`basic-sender`](basic-sender.md) |
| 144 | +- [`basic-receiver`](basic-receiver.md.nolink) |
| 145 | +- [`execution::operation_state`](operation_state.md) |
| 146 | + |
| 147 | + |
| 148 | +## 参照 |
| 149 | +- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html) |
0 commit comments