get.hpp #
These are functions for extracting values from toml::value
and performing type conversions if necessary.
toml::value
can change the type it stores, andtoml::get
accommodates these types. Technically, all functions usetoml::basic_value<TC>
. However, for simplicity, we refer to it astoml::value
in explanations unless a distinction is necessary. In the documentation, if the template parameterTC
changes the type, assume that types liketoml::value::integer_type
will also change accordingly.
toml::get<T>
#
Overview #
Generally, toml::get
behaves as follows:
You specify T
as in toml::get<int>(v)
.
template<typename T, typename TC>
T get(const basic_value<TC>& v);
However, depending on the type of T
, toml::get
can exhibit different behaviors.
The types of T
can be categorized into:
- Types that do not require conversion
- Types that require conversion
Detailed conditions and the specific types supported are discussed later.
Types that Do Not Require Conversion #
No conversion is needed if the provided toml::value
is already storing the desired type. For instance, since toml::value::integer_type
is an alias for std::int64_t
, toml::get<std::int64_t>(v)
requires no conversion. In this case, toml::get
retrieves the integer
value from toml::value
and returns a reference to it.
If the provided toml::value
is a mutable reference (&
), the returned value is also a mutable reference (&
). If it is an immutable reference (const&
), the returned value will also be an immutable reference (const&
). Returning a mutable reference allows you to overwrite the value stored in toml::value
through that reference.
Types that Require Conversion #
Types other than the ones mentioned above require conversion. For example, since toml::value::integer_type
is an alias for std::int64_t
, toml::get<std::size_t>(toml::value&)
requires conversion. In this case, toml::get
retrieves the integer
value from toml::value
and casts it to return the appropriate type.
toml11 supports not only simple casts but also complex type conversions like converting from toml::array
to std::tuple<int, double, std::string>
, std::array<double, 4>
, or from toml::table
to std::map<std::string, int>
. For specifics, refer to the subsequent sections.
When Conversion Fails #
Sometimes, the expected type conversion cannot be performed. For example, applying toml::get<int>(v)
to a toml::value
that holds a table
.
In such cases, an attempt to convert to the type most similar to the desired type (in this case, int
using as_integer
) fails, and a toml::type_error
is thrown.
When parsing from a file, an error message similar to the following is output:
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
When T
is identical to toml::value
#
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);
Condition:
std::is_same<T, basic_value<TC>>
is satisfied.
Since this involves retrieving toml::value
from toml::value
, no conversion is performed, and the value is returned as is. This exists solely to generalize the implementation of other functions.
This does not fail.
When T
is one of 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);
Condition:
T
must be the same as one of the types thattoml::value
can store (e.g.,toml::value::boolean_type
).
If toml::value
is storing a type that matches the specified type in toml::get<T>
, such as toml::value::integer_type
, no type conversion is needed, and a reference can be returned.
If a different type is stored, a toml::type_error
is thrown.
When T
is basic_value<OtherTC>
with a different TypeConfig
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
T
is nottoml::basic_value<TC>
.T
istoml::basic_value<OtherTC>
.
When a basic_value
that can store different types is specified, conversion is performed.
Since type conversion occurs, the returned value is a new value and not a reference.
This does not fail (except in cases like memory exhaustion).
When T
is an integer type
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
std::is_integral<T>
is satisfiedT
is notbool
T
is nottoml::value::integer_type
The function assumes that toml::value
holds an integer_type
, retrieves its value, converts it to T
, and returns it.
If a type other than toml::value::integer_type
is stored, a toml::type_error
is thrown.
When T
is a floating-point type
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
std::is_floating_point<T>
is satisfiedT
is nottoml::value::floating_type
The function assumes that toml::value
holds a floating_type
, retrieves its value, converts it to T
, and returns it.
If a type other than toml::value::floating_type
is stored, a toml::type_error
is thrown.
When T
is std::string_view
#
This is only available in C++17 and later.
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
std::is_same<std::string_view, T>
is satisfied
The function assumes that toml::value
holds a string_type
, retrieves its value, constructs a std::string_view
from it, and returns it.
If a type other than toml::value::string_type
is stored, a toml::type_error
is thrown.
When T
is std::chrono::duration
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
T
isstd::chrono::duration<Rep, Period>
The function assumes that toml::value
holds a local_time
, retrieves its value, converts it to std::chrono::duration
, and returns it.
If a type other than toml::value::local_time
is stored, a toml::type_error
is thrown.
When T
is std::chrono::system_clock::time_point
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
std::is_same<T, std::chrono::system_clock::time_point>
is satisfied
If the toml::value
holds a local_date
, local_datetime
, or offset_datetime
, this function retrieves the value and converts it to std::chrono::system_clock::time_point
, returning the result.
If the value is of a type other than local_date
, local_datetime
, or offset_datetime
, a toml::type_error
is thrown.
When T
is array-like
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Conditions:
T
has aniterator
T
has avalue_type
T
supportspush_back(x)
T
is nottoml::value::array_type
T
is notstd::string
T
is notstd::string_view
T
is not map-likeT
does not havefrom_toml()
member functiontoml::from<T>
is not defined- A constructor from
toml::basic_value<TC>
is not defined
This includes types like std::vector<int>
and std::deque<std::string>
.
If the toml::value
holds an array
, this function retrieves the value and converts it to the specified container type, returning the result.
If the value is of a type other than toml::value::array_type
, a toml::type_error
is thrown.
When T
is std::array
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
条件:
T
isstd::array<U, N>
If the toml::value
holds an array
, this function retrieves the value and converts it to the specified container type, returning the result.
If the value is of a type other than toml::value::array_type
, a toml::type_error
is thrown.
If the array
held by toml::value
does not contain enough elements, a std::out_of_range
is thrown.
When T
is std::forward_list
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
T
isstd::forward_list<U>
If the toml::value
holds an array
, this function retrieves the value and converts it to a std::forward_list
, returning the result.
If the value is of a type other than toml::value::array_type
, a toml::type_error
is thrown.
When T
is std::pair
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
T
isstd::pair<T1, T2>
If the toml::value
holds an array
, this function retrieves the value and converts it to std::pair<T1, T2>
, returning the result.
The first
and second
elements are recursively converted.
If the value is of a type other than basic_value::array_type
, a toml::type_error
is thrown.
If the array
held by toml::value
does not contain exactly 2 elements, a std::out_of_range
is thrown.
When T
is std::tuple
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
T
isstd::tuple<T1, T2, ... TN>
If the toml::value
holds an array
, this function retrieves the value and converts it to std::tuple<T1, T2, ...TN>
, returning the result.
Each element is recursively converted.
If the value is of a type other than basic_value::array_type
, a toml::type_error
is thrown.
If the array
held by toml::value
does not contain exactly std::tuple_size<T>::value
elements, a std::out_of_range
is thrown.
When T
is map-like
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Conditions:
T
has aniterator
T
has akey_type
T
has avalue_type
T
has amapped_type
T
is nottoml::value::table_type
T
does not have afrom_toml()
member functiontoml::from<T>
is not defined- A constructor from
toml::basic_value<TC>
is not defined
This includes types like std::map<std::string, int>
and std::unordered_map<std::string, float>
.
If the toml::value
holds a table
, this function retrieves the value and converts it to T
, returning the result.
Elements are recursively converted.
If the value is of a type other than basic_value::table_type
, a toml::type_error
is thrown.
When T
is a user-defined type with a specialization of toml::from<T>
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Condition:
- A specialization of
toml::from<T>
is defined
If a specialization of toml::from
for T
is defined, it is used for type conversion.
Ensure this does not conflict with individually supported types (std::array
, std::pair
, std::tuple
etc).
When T
is a user-defined type with a from_toml
member function
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Conditions:
toml::from<T>
is not definedT
hasfrom_toml()
member function
If T
has a from_toml(toml::basic_value<TC>)
member function, it is used for type conversion.
If toml::from<T>
is defined, it takes precedence.
When T
is a user-defined type with a constructor that takes toml::basic_value<TC>
#
template<typename T, typename TC>
T get(basic_value<TC>& v);
Conditions:
toml::from<T>
is not definedT
does not havefrom_toml()
member functionT
has a constructor that takestoml::basic_value<TC>
If T
has a constructor that takes toml::basic_value<TC>
, it is used for type conversion.
If toml::from<T>
or T::from_toml
is defined, they take precedence.
toml::get_or<T>
#
get_or
takes a default value for use when the conversion fails, avoiding exceptions.
The default value must be of the same type as the target type T
.
Therefore, unlike toml::get<T>
, T
can be inferred in get_or
.
When T
is 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)
Since the conversion target is the same toml::value
, this never fails.
It exists solely to generalize the implementation of other functions.
When T
is 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
Performs the same conversion as toml::get<T>
. If it fails, the second argument is returned.
When T
is 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);
When const char*
is passed, the conversion target is interpreted as std::string
.
When T
is something else
#
template<typename TC>
typename std::remove_cv<typename std::remove_reference<T>::type>::type
get_or(const basic_value<TC>& v, T&& opt);
Performs the same conversion as toml::get<T>
. If it fails, the second argument is returned.