get.hpp

get.hpp #

toml::valueから値を取り出し、同時に(必要な場合)型変換を行う関数です。

toml::value は格納する型を変更でき、toml::getはそれらに対応しているので、 厳密には全て toml::basic_value<TC> が使われています。ただしこれでは冗長なので、 関数の宣言と特に区別しなければならない場合を除いて、簡単のため説明文では toml::value と書きます。 説明文では、テンプレートパラメータTCを変更して型が変更されていれば toml::value::integer_type などの型は追従して変更されると解釈してください。

toml::get<T> #

概要 #

基本的に、toml::getは以下のような関数として振る舞います。 Ttoml::get<int>(v)のようにして与えます。

template<typename T, typename TC>
T get(const basic_value<TC>& v);

ただし、Tがどのような型であるかによって、toml::getは異なる挙動をします。

Tの型の種類は、

  1. 変換が必要ない型
  2. 変換する必要がある型

に分けられます。

細かい条件と、特別にサポートしている具体的な型については後述します。

変換が必要ない型 #

変換が必要ないのは、渡された toml::value が格納している型です。 例えば、 toml::value::integer_typestd::int64_t のエイリアスなので、 toml::get<std::int64_t>(v) は変換を必要としません。 この場合、 toml:getinteger の値を toml::value から取り出し、その参照を返します。

渡されたtoml::valueが可変参照(&)である場合、返す値も可変参照(&)です。 不変参照(const&)の場合、返す値も不変参照(const&)となります。 可変参照を返した場合、その参照を通してtoml::valueに格納されている値に上書きできます。

変換が必要な型 #

上記の型以外については変換が必要です。 例えば、toml::value::integer_typestd::int64_tのエイリアスなので、toml::get<std::size_t>(toml::value&)は変換が必要です。 この場合、toml:getintegerの値をtoml::valueから取り出し、それをキャストして返します。

toml11は簡単なキャストだけでなく、 toml::arrayからやstd::tuple<int, double, std::string>std::array<double, 4>toml::tableからstd::map<std::string, int>などの複雑な型変換をサポートします。 具体的には、続くセクションを参照してください。

失敗した場合 #

期待した型変換を行えない場合があります。例えば、tableを持っているtoml::valuetoml::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

Ttoml::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なので、変換は行われず、そのままの値が返されます。 他の関数の実装を一般化するためだけに存在しています。

失敗しません。

Ttoml::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);

条件:

  • Ttoml::valueが格納できる型(toml::value::boolean_typeなど)のどれかと同一であること

toml::value が格納している型と同じ型、例えば toml::value::integer_typetoml::get<T>T として指定されたとき、型変換の必要がないため参照を返すことが可能です。

異なる型が格納されていた場合、toml::type_error が送出されます。

Tが異なるTypeConfigを持つbasic_value<OtherTC>のとき #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • Ttoml::basic_value<TC>ではない
  • Ttoml::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::valueinteger_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::valuefloating_typeを保持しているとしてその値を取得し、それをTに変換して返します。

toml::value::floating_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

Tstd::string_viewの場合 #

C++17以降でのみ使用可能です。

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • std::is_same<std::string_view, T> を満たす

toml::valuestring_typeを保持しているとしてその値を取得し、それからstd::string_viewを構築して返します。

toml::value::string_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

Tstd::chrono::durationの場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • Tstd::chrono::duration<Rep, Period>である

toml::valuelocal_timeを保持しているとしてその値を取得し、それをstd::chrono::durationに変換して返します。

toml::value::local_time 以外の型が格納されていた場合、 toml::type_error が送出されます。

Tstd::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::valuelocal_date, local_datetime, offset_datetimeのどれかを保持しているとしてその値を取得し、それをstd::chrono::system_clock::time_pointに変換して返します。

local_date, local_datetime, offset_datetime 以外の型が格納されていた場合、 toml::type_error が送出されます。

Tarray-likeである場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • TT::iteratorを持つ
  • TT::value_typeを持つ
  • TT::push_back(x)を持つ
  • Ttoml::value::array_typeではない
  • Tstd::stringではない
  • Tstd::string_viewではない
  • Tmap-likeではない
  • Tfrom_toml()メンバ関数を持たない
  • toml::from<T>が定義されていない
  • toml::basic_value<TC>からのコンストラクタが定義されていない

std::vector<int>std::deque<std::string>などが該当します。

toml::valuearrayを保持しているとしてその値を取得し、それを指定されたコンテナに変換して返します。

toml::value::array_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

Tstd::arrayである場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • Tstd::array<U, N>である

toml::valuearrayを保持しているとしてその値を取得し、それを指定されたコンテナに変換して返します。

toml::value::array_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

toml::value が持つ array が十分な数の要素を持っていなかった場合、std::out_of_rangeが送出されます。

Tstd::forward_listである場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • Tstd::forward_list<U>である

toml::valuearrayを保持しているとしてその値を取得し、それをstd::forward_listに変換して返します。

toml::value::array_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

forward_listpush_backを持たないので、別に実装されています。

Tstd::pairである場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • Tstd::pair<T1, T2>である

toml::valuearrayを保持しているとしてその値を取得し、それをstd::pair<T1, T2>に変換して返します。

firstsecond はそれぞれ再帰的に変換されます。

toml::value::array_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

toml::value が持つ array の要素数がちょうど2個でなかった場合、std::out_of_rangeが送出されます。

Tstd::tupleである場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • Tstd::tuple<T1, T2, ... TN>である

toml::valuearrayを保持しているとしてその値を取得し、それをstd::tuple<T1, T2, ...TN>に変換して返します。

各要素はそれぞれ再帰的に変換されます。

toml::value::array_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

toml::value が持つ array の要素数がちょうど std::tuple_size<T>::value 個でなかった場合、std::out_of_rangeが送出されます。

Tmap-likeである場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • TT::iteratorを持つ
  • TT::key_typeを持つ
  • TT::value_typeを持つ
  • TT::mapped_typeを持つ
  • Ttoml::value::table_typeではない
  • Tfrom_toml()メンバ関数を持たない
  • toml::from<T>が定義されていない
  • toml::basic_value<TC>からのコンストラクタが定義されていない

std::map<std::string, int>std::unordered_map<std::string, float>などが該当します。

toml::valuetableを保持しているとしてその値を取得し、それを T に変換して返します。

各要素はそれぞれ再帰的に変換されます。

basic_value::table_type 以外の型が格納されていた場合、 toml::type_error が送出されます。

Ttoml::from<T>の特殊化を持つユーザー定義型である場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • toml::from<T>が定義されている

toml::fromT に対する特殊化が定義されていた場合、それを使用した型変換が行われます。

個別にサポートされる型( std::array, std::pair, std::tuple )と衝突しないようにしてください。

TT::from_tomlメンバ関数を持つユーザー定義型である場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • toml::from<T>が定義されていない
  • Tfrom_toml()メンバ関数を持つ

Tfrom_toml(toml::basic_value<TC>) メンバ関数が定義されていた場合、それを使用した型変換が行われます。

toml::from<T> が定義されていると、そちらが優先されます。

Ttoml::basic_value<TC>を取るコンストラクタを持つユーザー定義型である場合 #

template<typename T, typename TC>
T get(basic_value<TC>& v);

条件:

  • toml::from<T>が定義されていない
  • Tfrom_toml()メンバ関数を持たない
  • Ttoml::basic_value<TC>を取るコンストラクタを持つ

Ttoml::basic_value<TC> を取るコンストラクタが定義されていた場合、それを使用した型変換が行われます。

toml::from<T> または T::from_toml が定義されていると、そちらが優先されます。

toml::get_or<T> #

get_or は失敗した際のためのデフォルト値を受け取ることで、失敗時に例外を投げないようにします。

このデフォルト値は受け取る型Tと同じ型でなければなりません。 よって、 toml::get<T> とは違って、 get_or では T を指定せずとも推論されます。

Tbasic_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なので、失敗しません。

他の関数の実装を一般化するためだけに存在しています。

Tbasic_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>と同様の変換を行います。失敗した場合は第二引数が返されます。

Tconst 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>と同様の変換を行います。失敗した場合は第二引数が返されます。

関連項目 #