Skip to content

Commit 7bf378e

Browse files
committed
stop_token: (un)stoppable_token (#1384)
1 parent 494c6d2 commit 7bf378e

File tree

3 files changed

+173
-11
lines changed

3 files changed

+173
-11
lines changed

reference/stop_token.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,31 @@
77
- [`stop_token`](stop_token/stop_token.md), [`stop_source`](stop_token/stop_source.md), [`stop_callback`](stop_token/stop_callback.md)は停止状態を共有所有する。最後に破棄されたオブジェクトが停止状態を自動的に解放する。
88
- [`inplace_stop_source`](stop_token/inplace_stop_source.md.nolink)は停止状態をメンバとして直接所有する。[`inplace_stop_token`](stop_token/inplace_stop_token.md.nolink)[`inplace_stop_callback`](stop_token/inplace_stop_callback.md.nolink)は停止状態の所有には関与しない。
99

10+
## コンセプト
1011
| 名前 | 説明 | 対応バージョン |
11-
|-----------------------------------------------|------------------------------|-------|
12-
| [`stoppable_token`](stop_token/stoppable_token.md.nolink) | 停止可能な停止トークン(concept) | C++26 |
13-
| [`unstoppable_token`](stop_token/unstoppable_token.md.nolink) | 停止不可能な停止トークン(concept) | C++26 |
14-
| [`stop_token`](stop_token/stop_token.md) | 停止トークン(class) | C++20 |
15-
| [`stop_source`](stop_token/stop_source.md) | 停止要求を発生させるクラス(class) | C++20 |
12+
|------|------|-------|
13+
| [`stoppable_token`](stop_token/stoppable_token.md) | 停止トークン型であることを表す (concept) | C++26 |
14+
| [`unstoppable_token`](stop_token/unstoppable_token.md) | 停止不可能な停止トークン型であることを表す (concept) | C++26 |
15+
16+
## 停止トークン
17+
| 名前 | 説明 | 対応バージョン |
18+
|------|------|-------|
19+
| [`stop_token`](stop_token/stop_token.md) | 停止トークン (class) | C++20 |
20+
| [`stop_source`](stop_token/stop_source.md) | 停止要求を発生させるクラス (class) | C++20 |
1621
| [`stop_callback`](stop_token/stop_callback.md)| 停止要求に応じて呼び出されるコールバック (class template) | C++20 |
1722
| [`nostopstate`](stop_token/nostopstate.md) | 停止状態を扱わない[`stop_source`](stop_token/stop_source.md)を構築するためのタグ (class) | C++20 |
18-
| [`never_stop_token`](stop_token/never_stop_token.md.nolink) | 停止不可能な停止トークン(class) | C++26 |
19-
| [`inplace_stop_token`](stop_token/inplace_stop_token.md.nolink) | インプレース停止トークン(class) | C++26 |
20-
| [`inplace_stop_source`](stop_token/inplace_stop_source.md.nolink) | インプレース停止要求を発生させるクラス(class) | C++26 |
21-
| [`inplace_stop_callback`](stop_token/inplace_stop_callback.md.nolink) | インプレース停止要求に応じて呼び出されるコールバック(class template) | C++26 |
22-
| [`stop_callback_for_t`](stop_token/stop_callback_for_t.md.nolink) | 停止トークンに対応するコールバック型を取得(alias template) | C++26 |
23+
| [`never_stop_token`](stop_token/never_stop_token.md.nolink) | 停止不可能な停止トークン (class) | C++26 |
24+
| [`inplace_stop_token`](stop_token/inplace_stop_token.md.nolink) | インプレース停止トークン (class) | C++26 |
25+
| [`inplace_stop_source`](stop_token/inplace_stop_source.md.nolink) | インプレース停止要求を発生させるクラス (class) | C++26 |
26+
| [`inplace_stop_callback`](stop_token/inplace_stop_callback.md.nolink) | インプレース停止要求に応じて呼び出されるコールバック (class template) | C++26 |
27+
| [`stop_callback_for_t`](stop_token/stop_callback_for_t.md.nolink) | 停止トークンに対応するコールバック型を取得 (alias template) | C++26 |
2328

2429

2530
## バージョン
2631
### 言語
2732
- C++20
2833

2934
### 処理系
30-
3135
- [Clang](/implementation.md#clang): ??
3236
- [GCC](/implementation.md#gcc): ??
3337
- [ICC](/implementation.md#icc): ??
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# stoppable_token
2+
* stop_token[meta header]
3+
* concept[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class Token>
10+
concept stoppable_token;
11+
}
12+
```
13+
14+
## 概要
15+
`stoppable_token`は、型`Token`が停止トークンとしての基本的なインタフェースを提供することを表すコンセプトである。
16+
17+
18+
## 要件
19+
まず、説明専用クラステンプレート`check-type-alias-exists`を以下のように定義する。
20+
21+
```cpp
22+
template<template<class> class>
23+
struct check-type-alias-exists;
24+
```
25+
26+
`stoppable_token`コンセプトは、以下のように定義される。
27+
28+
```cpp
29+
template<class Token>
30+
concept stoppable_token =
31+
requires (const Token tok) {
32+
typename check-type-alias-exists<Token::template callback_type>;
33+
{ tok.stop_requested() } noexcept -> same_as<bool>;
34+
{ tok.stop_possible() } noexcept -> same_as<bool>;
35+
{ Token(tok) } noexcept;
36+
} &&
37+
copyable<Token> &&
38+
equality_comparable<Token> &&
39+
swappable<Token>;
40+
```
41+
* same_as[link /reference/concepts/same_as.md]
42+
* copyable[link /reference/concepts/copyable.md]
43+
* equality_comparable[link /reference/concepts/equality_comparable.md]
44+
* swappable[link /reference/concepts/swappable.md]
45+
46+
47+
## モデル
48+
49+
説明用の変数`t`, `u`を、同一の停止状態を参照する別々な`Token`型ブジェクトとする。
50+
型`Token`が以下を満たす場合に限って、型`Token`は`stoppable_token`のモデルである。
51+
52+
- `SP`を`t.stop_possible()`が`false`となる評価としたとき、`SP`より後に発生する`u.stop_possible()`や`u.stop_requested()`の評価は`false`であること。
53+
- `SR`を`t.stop_requested()`が`true`となる評価としたとき、`SR`より後に発生する`u.stop_possible()`や`u.stop_requested()`の評価は`true`であること。
54+
- `stoppable-callback-for<CallbackFn, Token, Initialize>`を満たす任意の型`CallbackFn`および型`Initialize`が、`stoppable-callback-for<CallbackFn, Token, Initializer>`のモデルであること。
55+
- `t`が停止状態を持たない(disengaged)とき、`t.stop_possible()`や`t.stop_requested()`の評価が`false`であること。
56+
- `t`と`u`が同一の停止状態を参照するか共に停止状態を持たない(disengaged)とき`t == u`が`true`であり、それ以外のときは`false`であること。
57+
58+
59+
ここで、説明専用コンセプト`stoppable-callback-for`を以下のように定義する。
60+
61+
```cpp
62+
template<class CallbackFn, class Token, class Initializer = CallbackFn>
63+
concept stoppable-callback-for =
64+
invocable<CallbackFn> &&
65+
constructible_from<CallbackFn, Initializer> &&
66+
requires { typename stop_callback_for_t<Token, CallbackFn>; } &&
67+
constructible_from<stop_callback_for_t<Token, CallbackFn>, const Token&, Initializer>;
68+
```
69+
* invocable[link /reference/concepts/invocable.md]
70+
* constructible_from[link /reference/concepts/constructible_from.md]
71+
* stop_callback_for_t[link stop_callback_for_t.md.nolink]
72+
73+
説明用の`init`[`same_as`](/reference/concepts/same_as.md)`<decltype(init), Initializer>`を満たす式、型`SCB`[`stop_callback_for_t`](stop_callback_for_t.md.nolink)`<Token, CallbackFn>`とする。
74+
75+
`stoppable-callback-for<CallbackFn, Token, Initializer>`のモデルとなるには、下記を満たすこと。
76+
77+
- 次のコンセプトのモデルであること。
78+
- [`constructible_from`](/reference/concepts/constructible_from.md)`<SCB, Token, Initializer>`
79+
- [`constructible_from`](/reference/concepts/constructible_from.md)`<SCB, Token&, Initializer>`
80+
- [`constructible_from`](/reference/concepts/constructible_from.md)`<SCB, const Token, Initializer>`
81+
- 説明用の`scb``SCB`型オブジェクト、`callback_fn``scb`に関連付けられた`CallbackFn`型のコールバック関数とする。引数`t``init`からの直接非リスト初期化`scb`は、次のように停止可能コールバック登録(stoppable callback registration)を実行すること。
82+
- `t.stop_possible() == true`のとき、
83+
- `callback_fn``init`で直接初期化される。
84+
- `scb`構築が送出する例外は、`init`からの`callback_fn`構築で送出された例外のみ。
85+
- コールバック呼び出し[`std::forward`](/reference/utility/forward.md)`<CallbackFn>(callback_fn)()`は、次のように`t`に関連する停止状態に登録されること。
86+
- 登録時点で`t.stop_requested()``false`に評価されるとき、コールバック呼び出しは停止状態のコールバックリストに追加され、停止状態に停止要求が行われたたときに[`std::forward`](/reference/utility/forward.md)`<CallbackFn>(callback_fn)()`が評価される。
87+
- そうでなければ、`scb`コンストラクタを実行したスレッド上で[`std::forward`](/reference/utility/forward.md)`<CallbackFn>(callback_fn)()`が即時実行され、コールバック呼び出しはリストに追加されない。
88+
- `t.stop_possible() == false`のとき、`callback_fn`の初期化による`scb`初期化には要求が課されない。
89+
- `scb`の破棄は、次のように停止可能コールバック登録解除(stoppable callback deregistration)を実行すること。
90+
- `scb`コンストラクタが`t`の停止状態にコールバック呼び出しを登録していなければ、停止可能コールバック登録解除は`callback_fn`破棄以外の効果を持たない。
91+
- そうでなければ、関連する停止状態から`callback_fn`の呼び出しが除外されること。
92+
- `callback_fn`が別スレッド上で並行実行中の場合、当該`callback_fn`呼び出しから戻るまで停止可能コールバック登録解除はブロックされる。この`callback_fn`呼び出しからの戻りは`callback_fn`の破棄よりも確実に前に発生する。
93+
- `callback_fn`が現在のスレッド上で実行中の場合、デストラクタは`callback_fn`からの戻りを待機してブロックしてはいけない。
94+
- 停止可能コールバック登録解除は、同じ停止状態に登録された他のコールバック呼び出しの完了をブロックしてはいけない。
95+
- 停止可能コールバック登録解除は`callback_fn`を破棄すること。
96+
97+
98+
## バージョン
99+
### 言語
100+
- C++26
101+
102+
### 処理系
103+
- [Clang](/implementation.md#clang): ??
104+
- [GCC](/implementation.md#gcc): ??
105+
- [ICC](/implementation.md#icc): ??
106+
- [Visual C++](/implementation.md#visual_cpp): ??
107+
108+
109+
## 関連項目
110+
- [`unstoppable_token`](unstoppable_token.md)
111+
- [`stop_token`](stop_token.md)
112+
- [`inplace_stop_token`](inplace_stop_token.md.nolink)
113+
- [`never_stop_token`](never_stop_token.md.nolink)
114+
115+
116+
## 参照
117+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# unstoppable_token
2+
* stop_token[meta header]
3+
* concept[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class Token>
10+
concept unstoppable_token =
11+
stoppable_token<Token> &&
12+
requires (const Token tok) {
13+
requires bool_constant<(!tok.stop_possible())>::value;
14+
};
15+
}
16+
```
17+
* stoppable_token[link stoppable_token.md]
18+
* bool_constant[link /reference/type_traits/bool_constant.md]
19+
20+
21+
## 概要
22+
`unstoppable_token`は、型`Token`が停止不可能な停止トークンであることを表すコンセプトである。
23+
24+
25+
## バージョン
26+
### 言語
27+
- C++26
28+
29+
### 処理系
30+
- [Clang](/implementation.md#clang): ??
31+
- [GCC](/implementation.md#gcc): ??
32+
- [ICC](/implementation.md#icc): ??
33+
- [Visual C++](/implementation.md#visual_cpp): ??
34+
35+
36+
## 関連項目
37+
- [`stoppable_token`](stoppable_token.md)
38+
- [`never_stop_token`](never_stop_token.md.nolink)
39+
40+
## 参照
41+
- [P2300R10 `std::execution`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2300r10.html)

0 commit comments

Comments
 (0)