Skip to content

Commit

Permalink
expected/expected.void: 全メンバ関数(#1066)
Browse files Browse the repository at this point in the history
  • Loading branch information
yohhoy committed Feb 9, 2023
1 parent 7c00cbc commit d55ed2f
Show file tree
Hide file tree
Showing 24 changed files with 1,424 additions and 42 deletions.
32 changes: 16 additions & 16 deletions reference/expected/expected.md
Expand Up @@ -86,38 +86,38 @@ namespace std {
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`operator=`](expected.void/op_assign.md.nolink) | 代入演算子 | C++23 |
| [`emplace`](expected.void/emplace.md.nolink) | 正常値型のコンストラクタ引数から直接構築する | C++23 |
| [`swap`](expected.void/swap.md.nolink) | 他の`expected`オブジェクトとデータを入れ替える | C++23 |
| [`operator=`](expected.void/op_assign.md) | 代入演算子 | C++23 |
| [`emplace`](expected.void/emplace.md) | 正常値を保持する | C++23 |
| [`swap`](expected.void/swap.md) | 他の`expected`オブジェクトとデータを入れ替える | C++23 |
### 値の観測
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`operator*`](expected.void/op_deref.md.nolink) | 正常値への間接参照 | C++23 |
| [`operator bool`](expected.void/op_bool.md.nolink) | 正常値を保持しているかを判定する | C++23 |
| [`has_value`](expected.void/has_value.md.nolink) | 正常値を保持しているかを判定する | C++23 |
| [`value`](expected.void/value.md.nolink) | 正常値を取得する | C++23 |
| [`error`](expected.void/error.md.nolink) | エラー値を取得する | C++23 |
| [`error_or`](expected.void/error_or.md.nolink) | エラー値もしくは指定された値を取得する | C++23 |
| [`operator*`](expected.void/op_deref.md) | 正常値への間接参照 | C++23 |
| [`operator bool`](expected.void/op_bool.md) | 正常値を保持しているかを判定する | C++23 |
| [`has_value`](expected.void/has_value.md) | 正常値を保持しているかを判定する | C++23 |
| [`value`](expected.void/value.md) | 正常値を取得する | C++23 |
| [`error`](expected.void/error.md) | エラー値を取得する | C++23 |
| [`error_or`](expected.void/error_or.md) | エラー値もしくは指定された値を取得する | C++23 |
(`expected<cv void, E>` 部分特殊化では、演算子オーバーロード`operator->`およびメンバ関数`value`は提供されない。)
(`expected<cv void, E>` 部分特殊化では、演算子オーバーロード`operator->`およびメンバ関数`value_or`は提供されない。)
### モナド操作
| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`and_then`](expected.void/and_then.md.nolink) | 正常値に対して関数を適用する | C++23 |
| [`or_else`](expected.void/or_else.md.nolink) | エラー値に対して関数を適用する | C++23 |
| [`transform`](expected.void/transform.md.nolink) | 正常値を変換する | C++23 |
| [`transform_error`](expected.void/transform_error.md.nolink) | エラー値を変換する | C++23 |
| [`and_then`](expected.void/and_then.md) | 正常値に対して関数を適用する | C++23 |
| [`or_else`](expected.void/or_else.md) | エラー値に対して関数を適用する | C++23 |
| [`transform`](expected.void/transform.md) | 正常値を変換する | C++23 |
| [`transform_error`](expected.void/transform_error.md) | エラー値を変換する | C++23 |
### 比較
| 名前 | 説明 | 対応バージョン |
|--------------|------------|-------|
| [`operator==`](expected.void/op_equal.md.nolink) | 等値比較 | C++23 |
| [`operator!=`](expected.void/op_not_equal.md.nolink) | 非等値比較 | C++23 |
| [`operator==`](expected.void/op_equal.md) | 等値比較 | C++23 |
| [`operator!=`](expected.void/op_not_equal.md) | 非等値比較 | C++23 |
## メンバ型
Expand Down
2 changes: 1 addition & 1 deletion reference/expected/expected.void.md
Expand Up @@ -21,4 +21,4 @@ namespace std {
このページは`expected<cv void, E>`部分特殊化テンプレートに対応するプレースホルダです。
`expected`クラスの説明は[`expected<E, E>`プライマリテンプレート](expected.md)ページを参照してください。
`expected`クラスの説明は[`expected<T, E>`プライマリテンプレート](expected.md)ページを参照してください。
136 changes: 136 additions & 0 deletions reference/expected/expected.void/and_then.md
@@ -0,0 +1,136 @@
# and_then
* expected[meta header]
* function template[meta id-type]
* std[meta namespace]
* expected.void[meta class]
* cpp23[meta cpp]

```cpp
// expected<cv void, E>部分特殊化
template<class F> constexpr auto and_then(F&& f) &; // (1)
template<class F> constexpr auto and_then(F&& f) const &; // (2)
template<class F> constexpr auto and_then(F&& f) &&; // (3)
template<class F> constexpr auto and_then(F&& f) const &&; // (4)
```
## 概要
正常値を保持していれば、`f`の呼び出し結果を`expected`として返す。
エラー値を保持していれば、そのまま返す。
実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。
`and_then`へは、引数をとらず`std::expected<Return, E>`型を返す関数や関数オブジェクトを与える。
```cpp
template <cv void, class E>
class expected {
template <class Return>
std::expected<Return, E> and_then(function<std::expected<Return, E>()> func);
};
```
* function[link /reference/functional/function.md]


## テンプレートパラメータ制約
- (1), (2) : [`is_copy_constructible_v`](/reference/type_traits/is_copy_constructible.md)`<E> == true`
- (3), (4) : [`is_move_constructible_v`](/reference/type_traits/is_move_constructible.md)`<E> == true`


## 適格要件
- (1), (2) : 型`U`[`remove_cvref_t`](/reference/type_traits/remove_cvref.md)`<`[`invoke_result_t`](/reference/type_traits/invoke_result.md)`<F>>`としたとき、次を全て満たすこと
- `U``expected`の特殊化である
- [`is_same_v`](/reference/type_traits/is_same.md)`<U::error_type, E> == true`
- (3), (4) : 型`U`[`remove_cvref_t`](/reference/type_traits/remove_cvref.md)`<`[`invoke_result_t`](/reference/type_traits/invoke_result.md)`<F>>`としたとき、次を全て満たすこと
- `U``expected`の特殊化である
- [`is_same_v`](/reference/type_traits/is_same.md)`<U::error_type, E> == true`


## 効果
- (1), (2) : 次の処理と等価
```cpp
if (has_value())
return invoke(std::forward<F>(f));
else
return U(unexpect, error());
```
* has_value[link has_value.md]
* error()[link error.md]
* unexpect[link ../unexpect_t.md]
* invoke[link /reference/functional/invoke.md]
* std::forward[link /reference/utility/forward.md]

- (3), (4) : 次の処理と等価
```cpp
if (has_value())
return invoke(std::forward<F>(f));
else
return U(unexpect, std::move(error()));
```
* has_value[link has_value.md]
* error()[link error.md]
* unexpect[link ../unexpect_t.md]
* invoke[link /reference/functional/invoke.md]
* std::forward[link /reference/utility/forward.md]
* std::move[link /reference/utility/move.md]


## 備考
`and_then`は、メソッドチェーンをサポートするモナド風(monadic)操作として導入された。


##
```cpp example
#include <cassert>
#include <expected>
#include <string>

std::expected<void, std::string> ok()
{
return {};
}

std::expected<void, std::string> ng()
{
return std::unexpected{"ng"};
}

int main()
{
std::expected<void, std::string> v1;
assert(v1.and_then(ok).has_value());

std::expected<void, std::string> v2;
assert(v2.and_then(ng).error() == "ng");

std::expected<void, std::string> e1 = std::unexpected{"empty"};
assert(e1.and_then(ng).error() == "empty");
}
```
* and_then[color ff0000]
* has_value()[link has_value.md]
* error()[link error.md]
* std::unexpected[link ../unexpected.md]

### 出力
```
```


## バージョン
### 言語
- C++23

### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): 13.0
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??


## 関連項目
- [`or_else()`](or_else.md)
- [`transform()`](transform.md)
- [`transform_error()`](transform_error.md)


## 参照
- [P2505R5 Monadic Functions for `std::expected`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2505r5.html)
55 changes: 55 additions & 0 deletions reference/expected/expected.void/emplace.md
@@ -0,0 +1,55 @@
# emplace
* expected[meta header]
* function[meta id-type]
* std[meta namespace]
* expected.void[meta class]
* cpp23[meta cpp]

```cpp
// expected<cv void, E>部分特殊化
constexpr void emplace() noexcept;
```

## 概要
正常値を保持する。


## 効果
正常値を保持していたら、何もしない。
エラー値を保持していたら、エラー値を破棄して正常値を保持する。


##
```cpp example
#include <cassert>
#include <expected>

int main()
{
std::expected<void, int> x = std::unexpected{42};
x.emplace();
assert(x.has_value());
}
```
* emplace[color ff0000]
* has_value()[link has_value.md]
* std::unexpected[link ../unexpected.md]

### 出力
```
```


## バージョン
### 言語
- C++23

### 処理系
- [Clang](/implementation.md#clang): 16.0
- [GCC](/implementation.md#gcc): 12.1
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??


## 参照
- [P0323R12 std::expected](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html)
75 changes: 75 additions & 0 deletions reference/expected/expected.void/error.md
@@ -0,0 +1,75 @@
# error
* expected[meta header]
* function[meta id-type]
* std[meta namespace]
* expected.void[meta class]
* cpp23[meta cpp]

```cpp
// expected<cv void, E>部分特殊化
constexpr const E& error() const & noexcept; // (1)
constexpr E& error() & noexcept; // (2)
constexpr const E&& error() const && noexcept; // (3)
constexpr E&& error() && noexcept; // (4)
```

## 概要
エラー値を取得する。


## 事前条件
[`has_value()`](has_value.md) `== false`


## 戻り値
動作説明用のメンバ変数として、エラー値を保持する`unex`を導入する。

- (1), (2) : エラー値を保持していたら、`unex`
- (3), (4) : エラー値を保持していたら、[`std::move`](/reference/utility/move.md)`(unex)`


## 例外
投げない


##
```cpp example
#include <cassert>
#include <expected>
#include <iostream>
#include <string>

int main()
{
std::expected<void, std::string> x = std::unexpected{"ERR"};
assert(not x.has_value());
std::cout << x.error() << std::endl;
}
```
* error()[color ff0000]
* has_value()[link has_value.md]
* std::unexpected[link ../unexpected.md]

### 出力
```
ERR
```


## バージョン
### 言語
- C++23

### 処理系
- [Clang](/implementation.md#clang): 16.0
- [GCC](/implementation.md#gcc): 12.1
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??


## 関連項目
- [`error_or`](error_or.md)


## 参照
- [P0323R12 std::expected](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html)
69 changes: 69 additions & 0 deletions reference/expected/expected.void/error_or.md
@@ -0,0 +1,69 @@
# error_or
* expected[meta header]
* function template[meta id-type]
* std[meta namespace]
* expected.void[meta class]
* cpp23[meta cpp]

```cpp
// expected<cv void, E>部分特殊化
template<class G = E> constexpr T error_or(G&& e) const &; // (1)
template<class G = E> constexpr T error_or(G&& e) &&; // (2)
```
## 概要
エラー値もしくは指定された値を取得する。
## 適格要件
- (1) : [`is_copy_constructible_v`](/reference/type_traits/is_copy_constructible.md)`<E> == true &&` [`is_convertible_v`](/reference/type_traits/is_convertible.md)`<G, E> == true`
- (2) : [`is_move_constructible_v`](/reference/type_traits/is_move_constructible.md)`<E> == true &&` [`is_convertible_v`](/reference/type_traits/is_convertible.md)`<G, E> == true`
## 戻り値
- (1) : [`has_value()`](has_value.md) `?` [`std::forward`](/reference/utility/forward.md)`<G>(e) :` [`error()`](error.md)
- (2) : [`has_value()`](has_value.md) `?` [`std::forward`](/reference/utility/forward.md)`<G>(e) :` [`std::move`](/reference/utility/move.md)`(`[`error()`](error.md)`)`
## 例
```cpp example
#include <expected>
#include <iostream>
#include <string>
int main()
{
std::expected<void, std::string> x;
std::cout << x.error_or("-") << std::endl;
std::expected<void, std::string> y = std::unexpected{"ERR"};
std::cout << y.error_or("-") << std::endl;
}
```
* error_or[color ff0000]
* std::unexpected[link ../unexpected.md]

### 出力
```
-
ERR
```


## バージョン
### 言語
- C++23

### 処理系
- [Clang](/implementation.md#clang): ??
- [GCC](/implementation.md#gcc): 13.0
- [ICC](/implementation.md#icc): ??
- [Visual C++](/implementation.md#visual_cpp): ??


## 関連項目
- [`error()`](error.md)


## 参照
- [P0323R12 std::expected](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html)

0 comments on commit d55ed2f

Please sign in to comment.