+++ title = "get.hpp" type = "docs" +++ # get.hpp `toml::value`から値を取り出し、同時に(必要な場合)型変換を行う関数です。 {{< hint info >}} `toml::value` は格納する型を変更でき、`toml::get`はそれらに対応しているので、 厳密には全て `toml::basic_value` が使われています。ただしこれでは冗長なので、 関数の宣言と特に区別しなければならない場合を除いて、簡単のため説明文では `toml::value` と書きます。 説明文では、テンプレートパラメータ`TC`を変更して型が変更されていれば `toml::value::integer_type` などの型は追従して変更されると解釈してください。 {{< /hint >}} # `toml::get` ## 概要 基本的に、`toml::get`は以下のような関数として振る舞います。 `T`は`toml::get(v)`のようにして与えます。 ```cpp template T get(const basic_value& v); ``` ただし、`T`がどのような型であるかによって、`toml::get`は異なる挙動をします。 `T`の型の種類は、 1. 変換が必要ない型 2. 変換する必要がある型 に分けられます。 細かい条件と、特別にサポートしている具体的な型については後述します。 ### 変換が必要ない型 変換が必要ないのは、渡された `toml::value` が格納している型です。 例えば、 `toml::value::integer_type` は `std::int64_t` のエイリアスなので、 `toml::get(v)` は変換を必要としません。 この場合、 `toml:get` は `integer` の値を `toml::value` から取り出し、その参照を返します。 渡された`toml::value`が可変参照(`&`)である場合、返す値も可変参照(`&`)です。 不変参照(`const&`)の場合、返す値も不変参照(`const&`)となります。 可変参照を返した場合、その参照を通して`toml::value`に格納されている値に上書きできます。 ### 変換が必要な型 上記の型以外については変換が必要です。 例えば、`toml::value::integer_type`は`std::int64_t`のエイリアスなので、`toml::get(toml::value&)`は変換が必要です。 この場合、`toml:get`は`integer`の値を`toml::value`から取り出し、それをキャストして返します。 toml11は簡単なキャストだけでなく、 `toml::array`からや`std::tuple`や`std::array`、 `toml::table`から`std::map`などの複雑な型変換をサポートします。 具体的には、続くセクションを参照してください。 ### 失敗した場合 期待した型変換を行えない場合があります。例えば、`table`を持っている`toml::value`に`toml::get(v)`を適用した場合などです。 このような場合は、取り出そうとした型に最も似ている型への変換(今回は`int`なので、`as_integer`)が失敗したとして、`toml::type_error`が送出されます。 ファイルからパースした場合、以下のようなエラーメッセージが出力されます。 ``` terminate called after throwing an instance of 'toml::type_error' what(): toml::value::as_integer(): bad_cast to integer --> input.toml | 6 | [fruit] | ^^^^^^^-- the actual type is table ``` ## `T`が`toml::value`と同一のとき ```cpp template< T, typename TC> T& get(basic_value& v); template T const& get(const basic_value& v); template T get(basic_value&& v); ``` 条件: - `std::is_same>` を満たす `toml::value`から`toml::value`なので、変換は行われず、そのままの値が返されます。 他の関数の実装を一般化するためだけに存在しています。 失敗しません。 ## `T`が`toml::value::{some_type}`のいずれかのとき ```cpp template T& get(basic_value& v); template T const& get(const basic_value& v); template T get(basic_value&& v); ``` 条件: - `T`が`toml::value`が格納できる型(`toml::value::boolean_type`など)のどれかと同一であること `toml::value` が格納している型と同じ型、例えば `toml::value::integer_type` が `toml::get` の `T` として指定されたとき、型変換の必要がないため参照を返すことが可能です。 異なる型が格納されていた場合、`toml::type_error` が送出されます。 ## `T`が異なる`TypeConfig`を持つ`basic_value`のとき ```cpp template T get(basic_value& v); ``` 条件: - `T`が`toml::basic_value`ではない - `T`が`toml::basic_value`である 異なる型を格納し得る`basic_value`が指定された場合、変換が行われます。 型変換が発生するので、返す値は新規な値であり、参照ではありません。 失敗しません(メモリ枯渇などの場合を除く)。 ## `T`が整数型の場合 ```cpp template T get(basic_value& v); ``` 条件: - `std::is_integral` を満たす - `std::is_same` ではない - `toml::value::integer_type` ではない `toml::value` を `integer_type` を保持しているとしてその値を取得し、それを `T` に変換して返します。 `toml::value::integer_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が浮動小数点数型の場合 ```cpp template T get(basic_value& v); ``` 条件: - `std::is_floating_point` を満たす - `toml::value::floating_type` ではない `toml::value`を`floating_type`を保持しているとしてその値を取得し、それを`T`に変換して返します。 `toml::value::floating_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が`std::string_view`の場合 C++17以降でのみ使用可能です。 ```cpp template T get(basic_value& v); ``` 条件: - `std::is_same` を満たす `toml::value`を`string_type`を保持しているとしてその値を取得し、それから`std::string_view`を構築して返します。 `toml::value::string_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が`std::chrono::duration`の場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`が`std::chrono::duration`である `toml::value`を`local_time`を保持しているとしてその値を取得し、それを`std::chrono::duration`に変換して返します。 `toml::value::local_time` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が`std::chrono::system_clock::time_point`の場合 ```cpp template T get(basic_value& v); ``` 条件: - `std::is_same`を満たす `toml::value` を `local_date`, `local_datetime`, `offset_datetime`のどれかを保持しているとしてその値を取得し、それを`std::chrono::system_clock::time_point`に変換して返します。 `local_date`, `local_datetime`, `offset_datetime` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が`array-like`である場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`は`T::iterator`を持つ - `T`は`T::value_type`を持つ - `T`は`T::push_back(x)`を持つ - `T`は`toml::value::array_type`ではない - `T`は`std::string`ではない - `T`は`std::string_view`ではない - `T`は`map-like`ではない - `T`は`from_toml()`メンバ関数を持たない - `toml::from`が定義されていない - `toml::basic_value`からのコンストラクタが定義されていない `std::vector`や`std::deque`などが該当します。 `toml::value`を`array`を保持しているとしてその値を取得し、それを指定されたコンテナに変換して返します。 `toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が`std::array`である場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`は`std::array`である `toml::value`を`array`を保持しているとしてその値を取得し、それを指定されたコンテナに変換して返します。 `toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 `toml::value` が持つ `array` が十分な数の要素を持っていなかった場合、`std::out_of_range`が送出されます。 ## `T`が`std::forward_list`である場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`は`std::forward_list`である `toml::value`を`array`を保持しているとしてその値を取得し、それを`std::forward_list`に変換して返します。 `toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 `forward_list`は`push_back`を持たないので、別に実装されています。 ## `T`が`std::pair`である場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`は`std::pair`である `toml::value`を`array`を保持しているとしてその値を取得し、それを`std::pair`に変換して返します。 `first` と `second` はそれぞれ再帰的に変換されます。 `toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 `toml::value` が持つ `array` の要素数がちょうど2個でなかった場合、`std::out_of_range`が送出されます。 ## `T`が`std::tuple`である場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`は`std::tuple`である `toml::value`を`array`を保持しているとしてその値を取得し、それを`std::tuple`に変換して返します。 各要素はそれぞれ再帰的に変換されます。 `toml::value::array_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 `toml::value` が持つ `array` の要素数がちょうど `std::tuple_size::value` 個でなかった場合、`std::out_of_range`が送出されます。 ## `T`が`map-like`である場合 ```cpp template T get(basic_value& v); ``` 条件: - `T`は`T::iterator`を持つ - `T`は`T::key_type`を持つ - `T`は`T::value_type`を持つ - `T`は`T::mapped_type`を持つ - `T`は`toml::value::table_type`ではない - `T`は`from_toml()`メンバ関数を持たない - `toml::from`が定義されていない - `toml::basic_value`からのコンストラクタが定義されていない `std::map`や`std::unordered_map`などが該当します。 `toml::value`を`table`を保持しているとしてその値を取得し、それを `T` に変換して返します。 各要素はそれぞれ再帰的に変換されます。 `basic_value::table_type` 以外の型が格納されていた場合、 `toml::type_error` が送出されます。 ## `T`が`toml::from`の特殊化を持つユーザー定義型である場合 ```cpp template T get(basic_value& v); ``` 条件: - `toml::from`が定義されている `toml::from` の `T` に対する特殊化が定義されていた場合、それを使用した型変換が行われます。 個別にサポートされる型( `std::array`, `std::pair`, `std::tuple` )と衝突しないようにしてください。 ## `T`が`T::from_toml`メンバ関数を持つユーザー定義型である場合 ```cpp template T get(basic_value& v); ``` 条件: - `toml::from`が定義されていない - `T`は`from_toml()`メンバ関数を持つ `T` に `from_toml(toml::basic_value)` メンバ関数が定義されていた場合、それを使用した型変換が行われます。 `toml::from` が定義されていると、そちらが優先されます。 ## `T`が`toml::basic_value`を取るコンストラクタを持つユーザー定義型である場合 ```cpp template T get(basic_value& v); ``` 条件: - `toml::from`が定義されていない - `T`は`from_toml()`メンバ関数を持たない - `T`は`toml::basic_value`を取るコンストラクタを持つ `T` に `toml::basic_value` を取るコンストラクタが定義されていた場合、それを使用した型変換が行われます。 `toml::from` または `T::from_toml` が定義されていると、そちらが優先されます。 # `toml::get_or` `get_or` は失敗した際のためのデフォルト値を受け取ることで、失敗時に例外を投げないようにします。 このデフォルト値は受け取る型`T`と同じ型でなければなりません。 よって、 `toml::get` とは違って、 `get_or` では `T` を指定せずとも推論されます。 ## `T`が`basic_value`である場合 ```cpp template basic_value const& get_or(const basic_value& v, const basic_value& opt) template basic_value & get_or(basic_value& v, basic_value& opt) template basic_value get_or(basic_value&& v, basic_value&& opt) ``` 変換先は同一の`toml::value`なので、失敗しません。 他の関数の実装を一般化するためだけに存在しています。 ## `T`が`basic_value::{some_type}`である場合 ```cpp template T const& get_or(const basic_value& v, const T& opt) noexcept template T & get_or(basic_value& v, T& opt) noexcept template T get_or(basic_value&& v, T&& opt) noexcept ``` `toml::get`と同様の変換を行います。失敗した場合は第二引数が返されます。 ## `T`が`const char*`である場合 ```cpp template typename basic_value::string_type get_or(const basic_value& v, const typename basic_value::string_type::value_type* opt); ``` `const char*` が渡された場合、変換先は `std::string` として解釈されます。 ## `T`がその他の場合 ```cpp template typename std::remove_cv::type>::type get_or(const basic_value& v, T&& opt); ``` `toml::get`と同様の変換を行います。失敗した場合は第二引数が返されます。 # 関連項目 - [find.hpp]({{}}) - [from.hpp]({{}}) - [value.hpp]({{}})