Skip to content

Commit

Permalink
generator: 各種調整
Browse files Browse the repository at this point in the history
  • Loading branch information
yohhoy committed Jan 3, 2023
1 parent 27f5df0 commit ab69dd5
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 15 deletions.
21 changes: 13 additions & 8 deletions reference/generator/generator.md
Expand Up @@ -22,27 +22,28 @@ namespace std {
戻り値型`generator`のコルーチン(以下、ジェネレータコルーチン)では`co_yield`式を用いて値を生成する。`co_yield` [`std::ranges::elements_of`](/reference/ranges/elements_of.md)`(rng)`式を用いると、ジェネレータコルーチンから入れ子Range(`rng`)の各要素を逐次生成する。
ジェネレータコルーチンでは`co_await`式を利用できない。
ジェネレータコルーチンは遅延評価される。ジェネレータコルーチンが返す`generator`オブジェクトの利用側(以下、呼び出し側)で先頭要素[`begin`](generator/begin.md)を指すイテレータを間接参照するまで、ジェネレータコルーチンの本体処理は実行されない。
ジェネレータコルーチンは遅延評価される。ジェネレータコルーチンが返す`generator`オブジェクトの利用側(以下、呼び出し側)で先頭要素[`begin`](generator/begin.md)を指す[イテレータ](generator/iterator.md)を間接参照するまで、ジェネレータコルーチンの本体処理は実行されない。
呼び出し側がイテレータの間接参照を試みるとジェネレータコルーチンを再開(resume)し、ジェネレータコルーチン本体処理において`co_yield`式に到達すると生成値を保持して再び中断(suspend)する。呼び出し側ではイテレータの間接参照の結果として生成値を取得する。
### 説明用メンバ
`generator`では下記の説明用メンバ型を定義する。
- `value` == [`conditional_t`](/reference/type_traits/conditional.md)`<`[`is_void_v`](/reference/type_traits/is_void.md)`<V>,` [`remove_cvref_t`](/reference/type_traits/remove_cvref.md)`<Ref>, V>`
- `reference` == [`conditional_t`](/reference/type_traits/conditional.md)`<`[`is_void_v`](/reference/type_traits/is_void.md)`<V>, Ref&&, Ref>`
- `value` : [`conditional_t`](/reference/type_traits/conditional.md)`<`[`is_void_v`](/reference/type_traits/is_void.md)`<V>,` [`remove_cvref_t`](/reference/type_traits/remove_cvref.md)`<Ref>, V>`
- `reference` : [`conditional_t`](/reference/type_traits/conditional.md)`<`[`is_void_v`](/reference/type_traits/is_void.md)`<V>, Ref&&, Ref>`
- [`iterator`](generator/iterator.md) : ジェネレータが返すイテレータ型。
`generator`クラスの動作説明のため、下記の説明専用メンバを用いる
`generator`および[`promise_type`](generator/promise_type.md)の動作説明のため、下記の説明用メンバを用いる
- [`coroutine_handle`](/reference/coroutine/coroutine_handle.md)`<`[`promise_type`](generator/promise_type.md)`>` : コルーチンハンドル(`coroutine_`)
- [`unique_ptr`](/reference/memory/unique_ptr.md)`<`[`stack`](/reference/stack/stack.md)`<`[`coroutine_handle<>`](/reference/coroutine/coroutine_handle.md)`>>`: アクティブスタック(`active_`)
## 適格要件
- テンプレートパラメータ`Allocator`が`void`ではない場合、[`allocator_traits<Allocator>`](/reference/memory/allocator_traits.md)`::pointer`はポインタ型であること。
- メンバ型`value`はCV修飾されないオブジェクト型であること。
- メンバ型`reference`は参照型、または[`copy_constructible`](/reference/concepts/copy_constructible.md)のモデルであるCV修飾されないオブジェクト型であること。
- メンバ型`reference`が参照型の場合には`RRef` == [`remove_reference_t`](/reference/type_traits/remove_reference.md)`<reference>&&`、それ以外の場合には`RRef` == `reference`としたとき、それぞれ下記のモデルであること。
- テンプレートパラメータ`Allocator`が`void`ではない場合、[`allocator_traits`](/reference/memory/allocator_traits.md)`<Allocator>::pointer`はポインタ型であること。
- 説明用のメンバ型`value`はCV修飾されないオブジェクト型であること。
- 説明用のメンバ型`reference`は参照型、または[`copy_constructible`](/reference/concepts/copy_constructible.md)のモデルであるCV修飾されないオブジェクト型であること。
- 説明用のメンバ型`reference`が参照型の場合には`RRef` == [`remove_reference_t`](/reference/type_traits/remove_reference.md)`<reference>&&`、それ以外の場合には`RRef` == `reference`としたとき、それぞれ下記のモデルであること。
- [`common_reference_with`](/reference/concepts/common_reference_with.md)`<reference&&, value&>`
- [`common_reference_with`](/reference/concepts/common_reference_with.md)`<reference&&, RRef&&>`
- [`common_reference_with`](/reference/concepts/common_reference_with.md)`<RRef&&, const value&>`
Expand Down Expand Up @@ -98,12 +99,16 @@ std::generator<int> evens()

int main()
{
// ジェネレータにより生成されるレンジのうち
// 先頭から5個までの要素値を列挙する
for (int n : evens() | std::views::take(5)) {
std::cout << n << std::endl;
}
}
```
* std::generator[color ff0000]
* co_yield[link /lang/cpp20/coroutines.md]
* std::views::take[link /reference/ranges/take_view.md]

### 出力
```
Expand Down
4 changes: 2 additions & 2 deletions reference/generator/generator/iterator.md
Expand Up @@ -61,8 +61,8 @@ namespace std {
| 名前 | 説明 | 対応バージョン |
|-----|-----|-----|
| `bool operator==(const iterator& i, default_sentinel_t)` | 等値比較 | C++23 |
| `bool operator!=(const iterator& i, default_sentinel_t)` | 非等値比較 (`==`により使用可能) | C++23 |
| `bool operator==(const iterator&, default_sentinel_t)` | 等値比較 | C++23 |
| `bool operator!=(const iterator&, default_sentinel_t)` | 非等値比較 (`==`により使用可能) | C++23 |
## バージョン
Expand Down
4 changes: 3 additions & 1 deletion reference/generator/generator/promise_type.md
Expand Up @@ -17,10 +17,12 @@ namespace std {
## 概要
ジェネレータコルーチン動作を制御する[Promise型](/lang/cpp20/coroutines.md)。
プログラマが本クラスを直接利用することは想定されていない。
`generator::promise_type`クラスの動作説明のため、以下の説明専用メンバを用いる。
- [`add_pointer_t`](/reference/type_traits/add_pointer.md)`<`[`yielded`](../../generator.md)`>`型 : `value_`
- [`add_pointer_t`](/reference/type_traits/add_pointer.md)`<`[`yielded`](../generator.md)`>`型 : `value_`
- [`exception_ptr`](/reference/exception/exception_ptr.md)型 : `except_`
Expand Down
Expand Up @@ -11,6 +11,7 @@ auto final_suspend() noexcept;

## 概要
ジェネレータコルーチンの[最終サスペンドポイント](/lang/cpp20/coroutines.md)を制御するAwaitableオブジェクトを返す。
プログラマが本関数を直接利用することは想定されていない。


## 事前条件
Expand Down
Expand Up @@ -13,6 +13,7 @@ generator get_return_object() noexcept;
## 概要
ジェネレータ[コルーチン](/lang/cpp20/coroutines.md)の戻り値オブジェクトを生成する。
戻り値ジェネレータの[アクティブスタック](../../generator.md)を、空(empty)で初期化する。
プログラマが本関数を直接利用することは想定されていない。


## 戻り値
Expand Down
Expand Up @@ -12,6 +12,7 @@ suspend_always initial_suspend() const noexcept;

## 概要
ジェネレータコルーチンの[初期サスペンドポイント](/lang/cpp20/coroutines.md)を制御するAwaitableオブジェクトを返す。
プログラマが本関数を直接利用することは想定されていない。


## 戻り値
Expand Down
6 changes: 3 additions & 3 deletions reference/generator/generator/promise_type/op_new.md
Expand Up @@ -17,9 +17,9 @@ template<class This, class Alloc, class... Args>
requires same_as<Allocator, void> || convertible_to<const Alloc&, Allocator>
void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc, const Args&...);
```
* std::same_as[link /reference/concepts/same_as.md]
* same_as[link /reference/concepts/same_as.md]
* default_initializable[link /reference/concepts/default_initializable.md]
* std::convertible_to[link /reference/concepts/convertible_to.md]
* convertible_to[link /reference/concepts/convertible_to.md]
* allocator_arg_t[link /reference/memory/allocator_arg_t.md]
Expand All @@ -42,7 +42,7 @@ void* operator new(size_t size, const This&, allocator_arg_t, const Alloc& alloc
## 効果
`B`型のアロケータ`b`を、オーバーロード(1)では`A()`により、オーバーロード(2)(3)では`A(alloc)`により初期化する。
アロケータ`b`を用いて、サイズ`size`の[コルーチン・ステー](/lang/cpp20/coroutines.md)トと、後ほど[`operator delete`](op_delete.md)による`b`を用いたメモリブロック解放で必要とされる追加状態を合わせたストレージに必要となる、`U`型の最小配列ストレージを確保する。
アロケータ`b`を用いて、サイズ`size`の[コルーチン・ステート](/lang/cpp20/coroutines.md)、後ほど[`operator delete`](op_delete.md)による`b`を用いたメモリブロック解放で必要とされる追加状態を合わせたストレージに必要となる、`U`型の最小配列ストレージを確保する。
## 戻り値
Expand Down
1 change: 1 addition & 0 deletions reference/generator/generator/promise_type/return_void.md
Expand Up @@ -11,6 +11,7 @@ void return_void() const noexcept;

## 概要
ジェネレータコルーチンからreturn時の動作を制御する。
プログラマが本関数を直接利用することは想定されていない。


## 効果
Expand Down
Expand Up @@ -11,6 +11,7 @@ void unhandled_exception();

## 概要
ジェネレータコルーチンから送出された例外を処理する。
プログラマが本関数を直接利用することは想定されていない。


## 事前条件
Expand Down
3 changes: 2 additions & 1 deletion reference/generator/generator/promise_type/yield_value.md
Expand Up @@ -36,6 +36,7 @@ auto yield_value(ranges::elements_of<Rng, Alloc> r) noexcept; // (4)
## 概要
ジェネレータコルーチンにおける[co_yield式](/lang/cpp20/coroutines.md)の動作を制御する。
プログラマが本関数を直接利用することは想定されていない。
## 事前条件
Expand Down Expand Up @@ -79,7 +80,7 @@ return yield_value(ranges::elements_of(nested(
## 戻り値
- (1) : [`suspend_always{}`](/reference/coroutine/suspend_always.md)
- (1) : [`suspend_always{}`](/reference/coroutine/suspend_always.md)
- (2) : `lval`を用いて直接非リスト初期化(direct-non-list-initialized)された[`remove_cvref_t`](/reference/type_traits/remove_cvref.md)`<`[`yielded`](../../generator.md)`>`型オブジェクトを保持し、[説明専用メンバ`value_`](../promise_type.md)が保持されたオブジェクトを指してコルーチンを中断(suspend)するメンバ関数をもつ、未規定の型の[Awaitableオブジェクト](/lang/cpp20/coroutines.md)。
- (3) : ジェネレータ`g.range`の所有権を受け取り、メンバ関数`await_ready`は`false`を返し、メンバ関数`await_suspend`は`x`のアクティブスタックに`g.range`に対応する[コルーチンハンドル](/reference/coroutine/coroutine_handle.md)をpushしてから`g.range`を再開(resume)し、メンバ関数`await_resume`は[説明専用メンバ`except_`](../promise_type.md)が例外を保持している場合に[`rethrow_exception`](/reference/exception/rethrow_exception.md)`(except_)`を行う、未規定の型の[Awaitableオブジェクト](/lang/cpp20/coroutines.md)。
Expand Down

0 comments on commit ab69dd5

Please sign in to comment.