From f34854cf613a91f73823e1270b3eee6bca9dac9b Mon Sep 17 00:00:00 2001 From: yoh Date: Thu, 26 Jan 2023 22:51:58 +0900 Subject: [PATCH] =?UTF-8?q?expected:=20unexpected,unexpect=5Ft,bad=5Fexpec?= =?UTF-8?q?ted=5Faccess=E6=A6=82=E8=A6=81(#1066)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- reference/expected.md | 6 +- reference/expected/bad_expected_access.md | 81 ++++++++++++++ reference/expected/expected.md | 12 ++- reference/expected/unexpect_t.md | 61 +++++++++++ reference/expected/unexpected.md | 126 ++++++++++++++++++++++ 5 files changed, 278 insertions(+), 8 deletions(-) create mode 100644 reference/expected/bad_expected_access.md create mode 100644 reference/expected/unexpect_t.md create mode 100644 reference/expected/unexpected.md diff --git a/reference/expected.md b/reference/expected.md index 3794925f44..1c16e793e0 100644 --- a/reference/expected.md +++ b/reference/expected.md @@ -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 | ## バージョン diff --git a/reference/expected/bad_expected_access.md b/reference/expected/bad_expected_access.md new file mode 100644 index 0000000000..b4ec99ce13 --- /dev/null +++ b/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 bad_expected_access : public bad_expected_access { ... }; + + // void特殊化 + template<> + class bad_expected_access : 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 +#include +#include +#include + +int main() +{ + std::expected 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& 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` should have `error()` as member accessor](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2549r1.html) diff --git a/reference/expected/expected.md b/reference/expected/expected.md index b10bda8928..d05209c378 100644 --- a/reference/expected/expected.md +++ b/reference/expected/expected.md @@ -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 | ## メンバ型 @@ -77,7 +77,7 @@ namespace std { |-------------------|-----------------|-------| | `value_type` | 正常値の型`T` | C++23 | | `error_type` | エラー値の型`E` | C++23 | -| `unexpected_type` | [`unexpected`](unexpected.md.nolink) | C++23 | +| `unexpected_type` | [`unexpected`](unexpected.md) | C++23 | | `template rebind` | `expected` | C++23 | @@ -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" ``` @@ -138,6 +139,7 @@ divide by zero ## 関連項目 +- [`unexpected`](unexpected.md) - [`optional`](/reference/optional/optional.md) diff --git a/reference/expected/unexpect_t.md b/reference/expected/unexpect_t.md new file mode 100644 index 0000000000..9dd3e2d9bb --- /dev/null +++ b/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 +#include +#include + +int main() +{ + std::expected 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) diff --git a/reference/expected/unexpected.md b/reference/expected/unexpected.md new file mode 100644 index 0000000000..101eb5115f --- /dev/null +++ b/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 unexpected; +} +``` + +## 概要 +`unexpected`クラスは、任意の型`E`の値をエラー値として表現する。 + + +## 適格要件 +`E`は非オブジェクト型、配列型、`unexpected`、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 +#include +#include +#include + +// 整数除算 +std::expected 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& 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` should have `error()` as member accessor](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2549r1.html)