Skip to content

Commit 2705e5a

Browse files
committed
execution: as_awaitable (#1384)
class-type,single-sender,forwarding-query
1 parent 24f1d81 commit 2705e5a

File tree

9 files changed

+294
-9
lines changed

9 files changed

+294
-9
lines changed

reference/execution/class-type.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# class-type
2+
* execution[meta header]
3+
* concept[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class T>
10+
concept class-type = decays-to<T, T> && is_class_v<T>; // exposition only
11+
}
12+
```
13+
* decays-to[link decays-to.md]
14+
* is_class_v[link /reference/type_traits/is_class.md]
15+
16+
## 概要
17+
`class-type`は、型`T`がクラス型であることを表す説明専用のコンセプトである。
18+
19+
20+
## バージョン
21+
### 言語
22+
- C++26
23+
24+
25+
## 参照
26+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)

reference/execution/execution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ Senderコンシューマは名前空間 `std::this_thread` で定義される。
151151
152152
| 名前 | 説明 | 対応バージョン |
153153
|------|------|----------------|
154-
| [`execution::as_awaitable`](execution/as_awaitable.md.nolink) | Senderを[Awaitable型](/lang/cpp20/coroutines.md)へ変換 (customization point object) | C++26 |
154+
| [`execution::as_awaitable`](execution/as_awaitable.md) | Senderを[Awaitable型](/lang/cpp20/coroutines.md)へ変換 (customization point object) | C++26 |
155155
| [`execution::with_awaitable_senders`](execution/with_awaitable_senders.md) | [Promise型](/lang/cpp20/coroutines.md)の基底クラス (class template) | C++26 |
156156
157157
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# as_awaitable
2+
* execution[meta header]
3+
* cpo[meta id-type]
4+
* std::execution[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std::execution {
9+
struct as_awaitable_t { unspecified };
10+
inline constexpr as_awaitable_t as_awaitable{};
11+
}
12+
```
13+
* unspecified[italic]
14+
15+
## 概要
16+
`as_awaitable`は、オブジェクトを特定コルーチン内でAwaitableに変換するカスタマイゼーションポイントオブジェクトである。
17+
18+
19+
## 効果
20+
説明用の式`expr`と左辺値`p`に対して、型`Expr`を`decltype((expr))`、型`Promise`を[`decay_t`](/reference/type_traits/decay.md)`<decltype((p))>`とする。
21+
22+
呼び出し式`as_awaitable(expr, p)`は、`expr`と`p`の評価が不定順で順序付けられることを除いて、下記と等価。
23+
24+
- 適格であるならば、式`expr.as_awaitable(p)`
25+
- 適格要件 : 同式の型を`A`としたとき、[`is-awaitable`](../is-awaitable.md)`<A, Promise> == true`であるべき。
26+
- そうではなく、説明用の型`U`を`Promise`とは異なりかつ`await_transform`メンバ関数を持たない未規定の型としたとき、[`is-awaitable`](../is-awaitable.md)`<Expr, U> == true`ならば、式`(void(p), expr)`
27+
- 事前条件 : [`is-awaitable`](../is-awaitable.md)`<Expr, Promise> == true`、かつPromise型`U`のコルーチンにおける式`co_await expr`がPromise型`Promise`のコルーチンにおける同式と等しさを保持すること。
28+
- そうではなく、`awaitable-sender<Expr, Promise>`ならば、式`sender-awaitable{expr, p}`
29+
- そうでなければ、式`(void(p), expr)`
30+
31+
32+
## 説明専用エンティティ
33+
### コンセプト`awaitable-sender`
34+
```cpp
35+
namespace std::execution {
36+
template<class Sndr, class Promise>
37+
concept awaitable-sender =
38+
single-sender<Sndr, env_of_t<Promise>> &&
39+
sender_to<Sndr, awaitable-receiver> && // see below
40+
requires (Promise& p) {
41+
{ p.unhandled_stopped() } -> convertible_to<coroutine_handle<>>;
42+
};
43+
}
44+
```
45+
* single-sender[link single-sender.md]
46+
* sender_to[link sender_to.md]
47+
* convertible_to[link /reference/concepts/convertible_to.md]
48+
* coroutine_handle<>[link /reference/coroutine/coroutine_handle.md]
49+
* see below[italic]
50+
51+
### クラステンプレート`sender-awaitable`
52+
```cpp
53+
namespace std::execution {
54+
template<class Sndr, class Promise>
55+
class sender-awaitable {
56+
struct unit {}; // exposition only
57+
using value-type = // exposition only
58+
single-sender-value-type<Sndr, env_of_t<Promise>>;
59+
using result-type = // exposition only
60+
conditional_t<is_void_v<value-type>, unit, value-type>;
61+
struct awaitable-receiver; // exposition only
62+
63+
variant<monostate, result-type, exception_ptr> result{}; // exposition only
64+
connect_result_t<Sndr, awaitable-receiver> state; // exposition only
65+
66+
public:
67+
sender-awaitable(Sndr&& sndr, Promise& p);
68+
static constexpr bool await_ready() noexcept { return false; }
69+
void await_suspend(coroutine_handle<Promise>) noexcept { start(state); }
70+
value-type await_resume();
71+
};
72+
}
73+
```
74+
* single-sender-value-type[link single-sender-value-type.md]
75+
* env_of_t[link env_of_t.md]
76+
* connect_result_t[link connect_result_t.md]
77+
* start[link start.md]
78+
* conditional_t[link /reference/type_traits/conditional.md]
79+
* is_void_v[link /reference/type_traits/is_void.md]
80+
* variant[link /reference/variant/variant.md]
81+
* monostate[link /reference/variant/monostate.md]
82+
* exception_ptr[link /reference/exception/exception_ptr.md]
83+
* coroutine_handle[link /reference/coroutine/coroutine_handle.md]
84+
85+
### クラステンプレート`awaitable-receiver`
86+
説明専用のクラステンプレート`sender-awaitable<Sndr, Promise>::awaitable-receiver`は下記の通り定義される。
87+
88+
```cpp
89+
struct awaitable-receiver {
90+
using receiver_concept = receiver_t;
91+
variant<monostate, result-type, exception_ptr>* result-ptr; // exposition only
92+
coroutine_handle<Promise> continuation; // exposition only
93+
// see below
94+
};
95+
```
96+
* receiver_t[link receiver.md]
97+
* variant[link /reference/variant/variant.md]
98+
* monostate[link /reference/variant/monostate.md]
99+
* exception_ptr[link /reference/exception/exception_ptr.md]
100+
* coroutine_handle[link /reference/coroutine/coroutine_handle.md]
101+
* see below[italic]
102+
103+
説明用の式`rcvr``awaitable-reciever`型の右辺値、`crcvr``rcvr`をconst参照する左辺値、`vs`を式パック、`err``Err`型の式とする。このとき
104+
105+
- [`constructible_from`](/reference/concepts/constructible_from.md)`<result-type, decltype((vs))...>`を満たすとき、式`set_value(rcvr, vs...)`は下記と等価。そうでなければ、式`set_value(rcvr, vs...)`は不適格となる。
106+
107+
```cpp
108+
try {
109+
rcvr.result-ptr->template emplace<1>(vs...);
110+
} catch(...) {
111+
rcvr.result-ptr->template emplace<2>(current_exception());
112+
}
113+
rcvr.continuation.resume();
114+
```
115+
* template emplace[link /reference/variant/variant/emplace.md]
116+
* current_exception()[link /reference/exception/current_exception.md]
117+
* resume()[link /reference/coroutine/coroutine_handle/resume.md]
118+
119+
-`set_error(rcvr, err)`は下記と等価。
120+
121+
```cpp
122+
rcvr.result-ptr->template emplace<2>(AS-EXCEPT-PTR(err));
123+
rcvr.continuation.resume();
124+
```
125+
* template emplace[link /reference/variant/variant/emplace.md]
126+
* resume()[link /reference/coroutine/coroutine_handle/resume.md]
127+
128+
- 式`set_stopped(rcvr)`は下記と等価。
129+
130+
```cpp
131+
static_cast<coroutine_handle<>>(rcvr.continuation.promise().unhandled_stopped()).resume();
132+
```
133+
* coroutine_handle<>[link /reference/coroutine/coroutine_handle.md]
134+
* promise()[link /reference/coroutine/coroutine_handle/promise.md]
135+
* resume()[link /reference/coroutine/coroutine_handle/resume.md]
136+
137+
- [`forwarding-query`](../forwarding-query.md)を満たす型の式`tag`とパック式`as`に対して、[`get_env`](get_env.md)`(crcvr).query(tag, as...)`は下記と等価。
138+
139+
```cpp
140+
tag(get_env(as_const(crcvr.continuation.promise())), as...)
141+
```
142+
* get_env[link get_env.md]
143+
* as_const[link /reference/utility/as_const.md]
144+
* promise()[link /reference/coroutine/coroutine_handle/promise.md]
145+
146+
```cpp
147+
sender-awaitable(Sndr&& sndr, Promise& p);
148+
```
149+
150+
- 効果 : `state`を下記で初期化する。
151+
152+
```cpp
153+
connect(std::forward<Sndr>(sndr),
154+
awaitable-receiver{addressof(result), coroutine_handle<Promise>::from_promise(p)})
155+
```
156+
* connect[link connect.md]
157+
* coroutine_handle[link /reference/coroutine/coroutine_handle.md]
158+
* from_promise[link /reference/coroutine/coroutine_handle/from_promise.md]
159+
160+
```cpp
161+
value-type await_resume();
162+
```
163+
164+
- 効果 : 下記と等価。
165+
166+
```cpp
167+
if (result.index() == 2)
168+
rethrow_exception(get<2>(result));
169+
if constexpr (!is_void_v<value-type>)
170+
return std::forward<value-type>(get<1>(result));
171+
```
172+
* index()[link /reference/variant/variant/index.md]
173+
* get[link /reference/variant/variant/get.md]
174+
* rethrow_exception[link /reference/exception/rethrow_exception.md]
175+
* is_void_v[link /reference/type_traits/is_void.md]
176+
177+
178+
## カスタマイゼーションポイント
179+
`expr`に対して、適格であるならば式`expr.as_awaitable(p)`が呼び出される。
180+
181+
182+
## バージョン
183+
### 言語
184+
- C++26
185+
186+
### 処理系
187+
- [Clang](/implementation.md#clang): ??
188+
- [GCC](/implementation.md#gcc): ??
189+
- [ICC](/implementation.md#icc): ??
190+
- [Visual C++](/implementation.md#visual_cpp): ??
191+
192+
193+
## 関連項目
194+
- [`execution::with_awaitable_senders`](with_awaitable_senders.md)
195+
- [C++20 コルーチン](/lang/cpp20/coroutines.md)
196+
197+
198+
## 参照
199+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)

reference/execution/execution/sender_adaptor_closure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace std::execution {
1010
struct sender_adaptor_closure { };
1111
}
1212
```
13-
* class-type[link class-type.md.nolink]
13+
* class-type[link ../class-type.md]
1414
1515
## 概要
1616
`sender_adaptor_closure`は、ユーザ定義のパイプ可能Senderアダプタクロージャオブジェクトの実装を補助するクラステンプレートである。

reference/execution/execution/single-sender-value-type.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ using single-sender-value-type = see below; // exposition only
2828
2929
## 関連項目
3030
- [`execution::stopped_as_optional`](stopped_as_optional.md)
31-
- [`sender-awaitable`](sender-awaitable.md.nolink)
31+
- [`execution::as_awaitable`](as_awaitable.md)
3232
3333
3434
## 参照
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# single-sender
2+
* execution[meta header]
3+
* type-alias[meta id-type]
4+
* std::execution[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
template<class Sndr, class Env>
9+
concept single-sender = sender_in<Sndr, Env> &&
10+
requires {
11+
typename single-sender-value-type<Sndr, Env>;
12+
};
13+
```
14+
* sender_in[link sender_in.md]
15+
* single-sender-value-type[link single-sender-value-type.md]
16+
17+
## 概要
18+
`single-sender`は、実行制御ライブラリの仕様定義で用いられる説明専用のエイリアステンプレートである。
19+
20+
21+
## バージョン
22+
### 言語
23+
- C++26
24+
25+
26+
## 関連項目
27+
- [`execution::as_awaitable`](as_awaitable.md)
28+
29+
30+
## 参照
31+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)

reference/execution/execution/with_awaitable_senders.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace std::execution {
3333
};
3434
}
3535
```
36-
* class-type[link class-type.md.nolink]
36+
* class-type[link ../class-type.md]
3737
* terminate()[link /reference/exception/terminate.md]
3838
* coroutine_handle[link /reference/coroutine/coroutine_handle.md]
3939
* address()[link /reference/coroutine/coroutine_handle/address.md]
@@ -173,7 +173,7 @@ value=42
173173
174174
175175
## 関連項目
176-
- [`execution::as_awaitable`](as_awaitable.md.nolink)
176+
- [`execution::as_awaitable`](as_awaitable.md)
177177
- [コルーチン](/lang/cpp20/coroutines.md)
178178
179179

reference/execution/execution/with_awaitable_senders/await_transform.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ call-result-t<as_awaitable_t, Value, Promise&>
1111
await_transform(Value&& value);
1212
```
1313
* call-result-t[link /reference/functional/call-result-t.md]
14-
* as_awaitable_t[link ../as_awaitable.md.nolink]
14+
* as_awaitable_t[link ../as_awaitable.md]
1515
1616
## 概要
17-
コルーチンの[`co_await`演算子](/lang/cpp20/coroutines.md)にアダプトし、[`as_awaitable`](../as_awaitable.md.nolink)で変換したAwaitableオブジェクトを返す。
17+
コルーチンの[`co_await`演算子](/lang/cpp20/coroutines.md)にアダプトし、[`as_awaitable`](../as_awaitable.md)で変換したAwaitableオブジェクトを返す。
1818
1919
2020
## 効果
@@ -23,7 +23,7 @@ call-result-t<as_awaitable_t, Value, Promise&>
2323
```cpp
2424
return as_awaitable(std::forward<Value>(value), static_cast<Promise&>(*this));
2525
```
26-
* as_awaitable[link ../as_awaitable.md.nolink]
26+
* as_awaitable[link ../as_awaitable.md]
2727

2828

2929
## バージョン
@@ -38,7 +38,7 @@ return as_awaitable(std::forward<Value>(value), static_cast<Promise&>(*this));
3838

3939

4040
## 関連項目
41-
- [`execution::as_awaitable`](../as_awaitable.md.nolink)
41+
- [`execution::as_awaitable`](../as_awaitable.md)
4242

4343

4444
## 参照
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# forwarding-query
2+
* execution[meta header]
3+
* concept[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class T>
10+
concept forwarding-query = forwarding_query(T{}); // exposition only
11+
}
12+
```
13+
* forwarding_query[link forwarding_query.md]
14+
15+
## 概要
16+
`forwarding_query`は、型`T`が[クエリ可能アダプタを通じて転送可能](forwarding_query.md)か否かを確認する説明専用のコンセプトである。
17+
18+
19+
## バージョン
20+
### 言語
21+
- C++26
22+
23+
24+
## 関連項目
25+
- [`forwarding_query`](forwarding_query.md)
26+
27+
28+
## 参照
29+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)

0 commit comments

Comments
 (0)