Skip to content

Commit

Permalink
expected: unexpected,unexpect_t,bad_expected_access概要(#1066)
Browse files Browse the repository at this point in the history
  • Loading branch information
yohhoy committed Jan 26, 2023
1 parent 1971c4d commit f34854c
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 8 deletions.
6 changes: 3 additions & 3 deletions reference/expected.md
Expand Up @@ -8,9 +8,9 @@
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`expected`](expected/expected.md) | 正常値かエラー値を保持するオブジェクト (class template) | C++23 |
| [`unexpected`](expected/unexpected.md.nolink) | エラー値の代入補助クラス (class template) | C++23 |
| [`unexpect_t`](expected/unexpect_t.md.nolink) | エラー値の直接構築を指示するタグ型 (class) | C++23 |
| [`bad_expected_access`](expected/bad_expected_access.md.nolink) | エラー値保持時に正常値へアクセスした場合に発生する例外 (class template) | C++23 |
| [`unexpected`](expected/unexpected.md) | エラー値の代入補助クラス (class template) | C++23 |
| [`unexpect_t`](expected/unexpect_t.md) | エラー値の直接構築を指示するタグ型 (class) | C++23 |
| [`bad_expected_access`](expected/bad_expected_access.md) | エラー値保持時に正常値へアクセスした場合に発生する例外 (class template) | C++23 |


## バージョン
Expand Down
81 changes: 81 additions & 0 deletions reference/expected/bad_expected_access.md
@@ -0,0 +1,81 @@
# bad_expected_access
* expected[meta header]
* class template[meta id-type]
* std[meta namespace]
* cpp23[meta cpp]

```cpp
namespace std {
template<class E>
class bad_expected_access : public bad_expected_access<void> { ... };

// void特殊化
template<>
class bad_expected_access<void> : public exception { ... };
}
```
* exception[link /reference/exception/exception.md]
## 概要
`bad_expected_access`は、[`expected`](expected.md)オブジェクトがエラー値を保持しているとき正常値にアクセスした場合に発生する例外である。
## メンバ関数
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`(constructor)`](bad_expected_access/op_constructor.md.nolink) | コンストラクタ | C++23 |
| `(destructor)` | デストラクタ | C++23 |
| [`error`](bad_expected_access/error.md.nolink) | エラー値を取得する | C++23 |
| [`what`](bad_expected_access/what.md.nolink) | エラー理由の文字列を取得する | C++23 |
## 例
```cpp example
#include <cassert>
#include <expected>
#include <iostream>
#include <string>
int main()
{
std::expected<int, std::string> x = std::unexpected{"invalid"};
try {
assert(not x.has_value());
int value = x.value(); // bad_expected_access例外発生
std::cout << "value: " << value << std::endl;
}
catch (const std::bad_expected_access<std::string>& ex) {
std::cout << "error: " << ex.error() << std::endl;
}
}
```
* std::bad_expected_access[color ff0000]
* std::unexpected[link unexpected.md]

### 出力
```
error: invalid
```


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

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


## 関連項目
- [`expected`](expected.md)
- [`bad_optional_access`](/reference/optional/bad_optional_access.md)


## 参照
- [P0323R12 std::expected](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html)
- [P2549R1 `std::unexpected<E>` should have `error()` as member accessor](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2549r1.html)
12 changes: 7 additions & 5 deletions reference/expected/expected.md
Expand Up @@ -67,8 +67,8 @@ namespace std {
| 名前 | 説明 | 対応バージョン |
|--------------|------------|-------|
| `operator==` | 等値比較 | C++23 |
| `operator!=` | 非等値比較 | C++23 |
| [`operator==`](unexpected/op_equal.md.nolink) | 等値比較 | C++23 |
| [`operator!=`](unexpected/op_not_equal.md.nolink) | 非等値比較 | C++23 |
## メンバ型
Expand All @@ -77,7 +77,7 @@ namespace std {
|-------------------|-----------------|-------|
| `value_type` | 正常値の型`T` | C++23 |
| `error_type` | エラー値の型`E` | C++23 |
| `unexpected_type` | [`unexpected<E>`](unexpected.md.nolink) | C++23 |
| `unexpected_type` | [`unexpected<E>`](unexpected.md) | C++23 |
| `template<class U> rebind` | `expected<U, error_type>` | C++23 |
Expand Down Expand Up @@ -117,12 +117,13 @@ int main()
}
```
* std::expected[color ff0000]
* std::unexpected[link unexpected.md]

### 出力
```
5
out of domain
divide by zero
"out of domain"
"divide by zero"
```


Expand All @@ -138,6 +139,7 @@ divide by zero


## 関連項目
- [`unexpected`](unexpected.md)
- [`optional`](/reference/optional/optional.md)


Expand Down
61 changes: 61 additions & 0 deletions reference/expected/unexpect_t.md
@@ -0,0 +1,61 @@
# unexpect_t
* expected[meta header]
* class[meta id-type]
* std[meta namespace]
* cpp23[meta cpp]

```cpp
namespace std {
struct unexpect_t {
explicit unexpect_t() = default;
};

inline constexpr unexpect_t {};
}
```
## 概要
`unexpected_t`は、[`expected`コンストラクタ](expected/op_constructor.md.nolink)において、エラー値型のコンストラクタ引数を受け取って構築するためのタグ型である。
`unexpected_t`型の定数`unexpect`が提供される。
## 例
```cpp example
#include <cassert>
#include <expected>
#include <system_error>
int main()
{
std::expected<int, std::error_code> x{std::unexpect, ETIMEDOUT, std::system_category()};
assert(not x.has_value());
assert(x.error().value() == ETIMEDOUT);
assert(x.error().category() == std::system_category());
}
```
* std::unexpect[color ff0000]
* ETIMEDOUT[link /reference/system_error/errc.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): ??


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


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

```cpp
namespace std {
template<class E>
class unexpected;
}
```
## 概要
`unexpected`クラスは、任意の型`E`の値をエラー値として表現する。
## 適格要件
`E`は非オブジェクト型、配列型、`unexpected<U>`、CV修飾された型のいずれでもないこと。
## メンバ関数
### 構築・破棄
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`(constructor)`](unexpected/op_constructor.md.nolink) | コンストラクタ | C++23 |
| [`(destructor)`](unexpected/op_destructor.md.nolink) | デストラクタ | C++23 |
### 代入
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`operator=`](unexpected/op_assign.md.nolink) | 代入演算子 | C++23 |
| [`swap`](unexpected/swap.md.nolink) | 他の`unexpected`オブジェクトとデータを入れ替える | C++23 |
### 値の観測
| 名前 | 説明 | 対応バージョン |
|-----------------|----------------|-------|
| [`error`](unexpected/error.md.nolink) | エラー値を取得する | C++23 |
### 比較
| 名前 | 説明 | 対応バージョン |
|--------------|------------|-------|
| [`operator==`](unexpected/op_equal.md.nolink) | 等値比較 | C++23 |
| [`operator!=`](unexpected/op_not_equal.md.nolink) | 非等値比較 | C++23 |
## 非メンバ関数
| 名前 | 説明 | 対応バージョン |
|------|------|-------|
| [`swap`](unexpected/swap_free.md.nolink) | 他の`unexpected`オブジェクトとデータを入れ替える | C++23 |
## 推論補助
| 名前 | 説明 | 対応バージョン |
|------|------|-------|
| [`(deduction_guide)`](unexpected/op_deduction_guide.md.nolink) | クラステンプレートの推論補助 | C++23 |
## 例
```cpp example
#include <expected>
#include <iomanip>
#include <iostream>
#include <string>
// 整数除算
std::expected<int, std::string> idiv(int a, int b)
{
if (b == 0) {
return std::unexpected{"divide by zero"};
}
if (a % b != 0) {
return std::unexpected{"out of domain"};
}
return a / b;
}
void dump_result(const std::expected<int, std::string>& v)
{
if (v) {
std::cout << *v << std::endl;
} else {
std::cout << std::quoted(v.error()) << std::endl;
}
}
int main()
{
dump_result(idiv(10, 2));
dump_result(idiv(10, 3));
dump_result(idiv(10, 0));
}
```
* std::unexpected[color ff0000]

### 出力
```
5
"out of domain"
"divide by zero"
```


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

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


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


## 参照
- [P0323R12 std::expected](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0323r12.html)
- [P2549R1 `std::unexpected<E>` should have `error()` as member accessor](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2549r1.html)

0 comments on commit f34854c

Please sign in to comment.