|
| 1 | +# simple_counting_scope |
| 2 | +* execution[meta header] |
| 3 | +* class[meta id-type] |
| 4 | +* std::execution[meta namespace] |
| 5 | +* cpp26[meta cpp] |
| 6 | + |
| 7 | +```cpp |
| 8 | +namespace std::execution { |
| 9 | + class simple_counting_scope; |
| 10 | +} |
| 11 | +``` |
| 12 | +
|
| 13 | +## 概要 |
| 14 | +`simple_counting_scope`は、カウント式の非同期スコープを表現する。 |
| 15 | +
|
| 16 | +
|
| 17 | +## クラス仕様 |
| 18 | +`simple_counting_scope`型と[`counting_scope`](counting_scope.md)型による非同期スコープは関連付けカウントを管理する。 |
| 19 | +
|
| 20 | +クラス動作説明用のメンバ変数として下記を保持する。 |
| 21 | +
|
| 22 | +- `count` : `size_t`型の関連付けカウント値 |
| 23 | +- `state` : `scope-state-type`列挙型(後述)の状態 |
| 24 | +
|
| 25 | +
|
| 26 | +### 状態遷移 |
| 27 | +説明専用の各種エンティティを下記の通り定義する。 |
| 28 | +
|
| 29 | +- `Scope`型 : `simple_counting_scope`または`counting_scope`のいずれか |
| 30 | +- `scope`オブジェクト : `Scope`型のオブジェクト |
| 31 | +- `tkn`オブジェクト : `scope.get_token()`が返す`Scope::token`型のオブジェクト |
| 32 | +- `jsndr` : `scope.join()`が返す[Sender](sender.md) |
| 33 | +- `op` : `jsndr`を[Receiver](receiver.md)と接続して得られる[Operation State](operation_state.md) |
| 34 | +
|
| 35 | +```cpp |
| 36 | +enum scope-state-type { // exposition only |
| 37 | + unused, // exposition only |
| 38 | + open, // exposition only |
| 39 | + closed, // exposition only |
| 40 | + open-and-joining, // exposition only |
| 41 | + closed-and-joining, // exposition only |
| 42 | + unused-and-closed, // exposition only |
| 43 | + joined, // exposition only |
| 44 | +}; |
| 45 | +``` |
| 46 | + |
| 47 | +`scope`はその生存期間中にさまざまな状態をとり、各状態で許可される操作とその結果を決定する: |
| 48 | + |
| 49 | +- `unused` : 新しく構築されたオブジェクトは`unused`状態で開始する。 |
| 50 | +- `open` : `scope`が`unused`状態にあるとき`tkn.try_associate()`が呼び出されると、`scope`は`open`状態に遷移する。 |
| 51 | +- `open-and-joining` : `scope`が`unused`または`open`状態にあるとき[Operation State](operation_state.md)`op`が[開始(start)](start.md)されると、`scope`は`open-and-joining`状態に遷移する。 |
| 52 | +- `closed` : `scope`が`open`状態にあるとき`scope.close()`が呼び出されると、`scope`は`closed`状態に遷移する。 |
| 53 | +- `unused-and-closed` : `scope`が`unused`状態にあるとき`scope.close()`が呼び出されると、`scope`は`unused-and-closed`状態に遷移する。 |
| 54 | +- `closed-and-joining` : `scope`が`open-and-joining`状態にあるとき`scope.close()`が呼び出される、もしくは`scope`が`closed`または`unused-and-closed`状態にあるとき[Operation State](operation_state.md)`op`が[開始(start)](start.md)されると、`scope`は`closed-and-joining`状態に遷移する。 |
| 55 | +- `joined` : `scope`が`open-and-joining`または`closed-and-joining`状態にあるとき関連付けカウントがゼロに到達すると、`scope`は`joined`状態に遷移する。 |
| 56 | + |
| 57 | + |
| 58 | +### Senderアルゴリズムタグ `scope-join-t` |
| 59 | +説明専用の[Senderアルゴリズムタグ型](tag_of_t.md)`scope-join-t`を定義する。 |
| 60 | + |
| 61 | +```cpp |
| 62 | +struct scope-join-t {}; // exposition only |
| 63 | +``` |
| 64 | +
|
| 65 | +Senderアルゴリズム動作説明用のクラステンプレート[`impls-for`](impls-for.md)に対して、下記の特殊化が定義される。 |
| 66 | +
|
| 67 | +```cpp |
| 68 | +namespace std::execution { |
| 69 | + template<> |
| 70 | + struct impls-for<scope-join-t> : default-impls { |
| 71 | + template<class Scope, class Rcvr> |
| 72 | + struct state { // exposition only |
| 73 | + struct rcvr-t { // exposition only |
| 74 | + using receiver_concept = receiver_t; |
| 75 | +
|
| 76 | + Rcvr& rcvr; // exposition only |
| 77 | +
|
| 78 | + void set_value() && noexcept { |
| 79 | + execution::set_value(std::move(rcvr)); |
| 80 | + } |
| 81 | +
|
| 82 | + template<class E> |
| 83 | + void set_error(E&& e) && noexcept { |
| 84 | + execution::set_error(std::move(rcvr), std::forward<E>(e)); |
| 85 | + } |
| 86 | +
|
| 87 | + void set_stopped() && noexcept { |
| 88 | + execution::set_stopped(std::move(rcvr)); |
| 89 | + } |
| 90 | +
|
| 91 | + decltype(auto) get_env() const noexcept { |
| 92 | + return execution::get_env(rcvr); |
| 93 | + } |
| 94 | + }; |
| 95 | +
|
| 96 | + using sched-sender = // exposition only |
| 97 | + decltype(schedule(get_scheduler(get_env(declval<Rcvr&>())))); |
| 98 | + using op-t = // exposition only |
| 99 | + connect_result_t<sched-sender, rcvr-t>; |
| 100 | +
|
| 101 | + Scope* scope; // exposition only |
| 102 | + Rcvr& receiver; // exposition only |
| 103 | + op-t op; // exposition only |
| 104 | +
|
| 105 | + state(Scope* scope, Rcvr& rcvr) // exposition only |
| 106 | + noexcept(nothrow-callable<connect_t, sched-sender, rcvr-t>) |
| 107 | + : scope(scope), |
| 108 | + receiver(rcvr), |
| 109 | + op(connect(schedule(get_scheduler(get_env(rcvr))), rcvr-t(rcvr))) {} |
| 110 | +
|
| 111 | + void complete() noexcept { // exposition only |
| 112 | + start(op); |
| 113 | + } |
| 114 | +
|
| 115 | + void complete-inline() noexcept { // exposition only |
| 116 | + set_value(std::move(receiver)); |
| 117 | + } |
| 118 | + }; |
| 119 | +
|
| 120 | + static constexpr auto get-state = // exposition only |
| 121 | + []<class Rcvr>(auto&& sender, Rcvr& receiver) |
| 122 | + noexcept(is_nothrow_constructible_v<state<Rcvr>, data-type<decltype(sender)>, Rcvr&>) { |
| 123 | + auto[_, self] = sender; |
| 124 | + return state(self, receiver); |
| 125 | + }; |
| 126 | +
|
| 127 | + static constexpr auto start = // exposition only |
| 128 | + [](auto& s, auto&) noexcept { |
| 129 | + if (s.scope->start-join-sender(s)) |
| 130 | + s.complete-inline(); |
| 131 | + }; |
| 132 | + }; |
| 133 | +} |
| 134 | +``` |
| 135 | +* impls-for[link impls-for.md] |
| 136 | +* default-impls[link impls-for.md] |
| 137 | +* receiver_t[link receiver.md] |
| 138 | +* execution::set_value[link set_value.md] |
| 139 | +* execution::set_error[link set_error.md] |
| 140 | +* execution::set_stopped[link set_stopped.md] |
| 141 | +* execution::get_env[link get_env.md] |
| 142 | +* schedule[link schedule.md] |
| 143 | +* get_scheduler[link get_scheduler.md] |
| 144 | +* connect_result_t[link connect_result_t.md] |
| 145 | +* connect_t[link connect.md] |
| 146 | +* connect[link connect.md] |
| 147 | +* start[link start.md] |
| 148 | +* data-type[link data-type.md] |
| 149 | +* nothrow-callable[link /reference/functional/nothrow-callable.md] |
| 150 | +* is_nothrow_constructible_v[link /reference/type_traits/is_nothrow_constructible.md] |
| 151 | +* std::move[link /reference/utility/move.md] |
| 152 | + |
| 153 | + |
| 154 | +## メンバ関数 |
| 155 | + |
| 156 | +| 名前 | 説明 | 対応バージョン | |
| 157 | +|------|------|----------------| |
| 158 | +| [`(constructor)`](simple_counting_scope/op_constructor.md.nolink) | コンストラクタ | C++26 | |
| 159 | +| [`(destructor)`](simple_counting_scope/op_destructor.md.nolink) | デストラクタ | C++26 | |
| 160 | +| [`get_token`](simple_counting_scope/get_token.md.nolink) | 非同期スコープトークンを取得 | C++26 | |
| 161 | +| [`close`](simple_counting_scope/close.md.nolink) | 非同期スコープを閉じる | C++26 | |
| 162 | +| [`join`](simple_counting_scope/join.md.nolink) | 非同期スコープを合流する[Sender](sender.md)取得 | C++26 | |
| 163 | + |
| 164 | +### 説明専用メンバ関数 |
| 165 | + |
| 166 | +| 名前 | 説明 | 対応バージョン | |
| 167 | +|------|------|----------------| |
| 168 | +| [`try-associate`](simple_counting_scope/try-associate.md.nolink) | 関連付けを試行 | C++26 | |
| 169 | +| [`disassociate`](simple_counting_scope/disassociate.md.nolink) | 関連付けを解除| C++26 | |
| 170 | +| [`start-join-sender`](simple_counting_scope/start-join-sender.md.nolink) | 合流[Sender](sender.md)を開始 | C++26 | |
| 171 | + |
| 172 | +## メンバ型 |
| 173 | + |
| 174 | +| 名前 | 説明 | 対応バージョン | |
| 175 | +|------|------|----------------| |
| 176 | +| [`token`](simple_counting_scope/token.md.nolink) | 非同期スコープトークン型 | C++26 | |
| 177 | + |
| 178 | +## 静的メンバ変数 |
| 179 | + |
| 180 | +| 名前 | 説明 | 対応バージョン | |
| 181 | +|------|------|----------------| |
| 182 | +| `constexpr size_t max_associations = implementation-defined;` | 関連付けの最大数 | C++26 | |
| 183 | + |
| 184 | + |
| 185 | +## バージョン |
| 186 | +### 言語 |
| 187 | +- C++26 |
| 188 | + |
| 189 | +### 処理系 |
| 190 | +- [Clang](/implementation.md#clang): ?? |
| 191 | +- [GCC](/implementation.md#gcc): ?? |
| 192 | +- [ICC](/implementation.md#icc): ?? |
| 193 | +- [Visual C++](/implementation.md#visual_cpp): ?? |
| 194 | + |
| 195 | + |
| 196 | +## 関連項目 |
| 197 | +- [`execution::counting_scope`](counting_scope.md) |
| 198 | + |
| 199 | + |
| 200 | +## 参照 |
| 201 | +- [P3149R11 `async_scope` - Creating scopes for non-sequential concurrency](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3149r11.html) |
0 commit comments