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