find.hpp #
This function searches for a value in a toml::value
and performs type conversion if necessary.
toml::value
can change the type it stores, andtoml::find
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::find
#
Overview #
toml::find
uses template arguments for the type you want to retrieve and function arguments for the key of the value you want to find.
template<typename T, typename TC, typename ... Keys>
T find(const basic_value<TC>& v, Keys ... keys);
The supported types for T
and the behavior of the conversion are the same as for toml::get
.
If T
is not specified, a toml::value
will be returned.
Keys can be of type toml::value::key_type
or std::size_t
.
When multiple keys are provided, the function will search recursively through sub-tables or arrays.
If a toml::value::key_type
is given, toml::value
is interpreted as a toml::table
; if a std::size_t
is given, toml::value
is interpreted as a toml::array
.
Note on Recursive Search #
TOML allows for bare keys as well as quoted keys (enclosed in "
or '
). Using a quoted key like "foo.bar" = "baz"
means no sub-table is constructed, and the key is "foo.bar"
. To handle such patterns, toml11 does not split keys containing .
and searches using the full string.
Consider the following TOML file:
[foo]
[foo.bar]
baz = "hoge"
["foo.bar"]
baz = "fuga"
The corresponding usage of toml::find
is shown below:
const auto input = toml::parse("input.toml");
const auto baz1 = toml::find<std::string>(input, "foo", "bar", "baz"); // hoge
const auto baz2 = toml::find<std::string>(input, "foo.bar", "baz"); // fuga
toml::find(value, key)
#
Searches for key
in value
as if value
were a toml::table
, then converts using toml::get
.
template<typename T, typename TC>
/* Equivalent to toml::get<T>(const value&) */ find(
const basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&) */ find(
basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&&) */ find(
basic_value<TC>&& v, const typename basic_value<TC>::key_type& ky);
If T
is not specified, the function returns a toml::value
without conversion.
template<typename TC>
basic_value<TC> const& find(
basic_value<TC> const& v, const typename basic_value<TC>::key_type& ky);
template<typename TC>
basic_value<TC>& find(
basic_value<TC>& v, const typename basic_value<TC>::key_type& ky);
template<typename TC>
basic_value<TC> find(
basic_value<TC>&& v, const typename basic_value<TC>::key_type& ky);
Exceptions #
If the toml::value
does not contain a table
, a toml::type_error
is thrown.
If the contained table
does not have the specified element, a std::out_of_range
is thrown.
If the specified element cannot be converted to T
(i.e., toml::get
fails), a toml::type_error
is thrown.
toml::find(value, index)
#
Accesses the index
-th element of value
as if value
were a toml::array
, then converts using toml::get
.
template<typename T, typename TC>
/* Equivalent to toml::get<T>(const value&) */ find(
const basic_value<TC>& v, const std::size_t index);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&) */ find(
basic_value<TC>& v, const std::size_t index);
template<typename T, typename TC>
/* Equivalent to toml::get<T>(value&&) */ find(
basic_value<TC>&& v, const std::size_t index);
If T
is not specified, the function returns a toml::value
without conversion.
template<typename TC>
basic_value<TC> const& find(basic_value<TC> const& v, const std::size_t ky);
template<typename TC>
basic_value<TC>& find(basic_value<TC>& v, const std::size_t ky);
template<typename TC>
basic_value<TC> find(basic_value<TC>&& v, const std::size_t ky);
Exceptions #
If the toml::value
does not contain an array
, a toml::type_error
is thrown.
If the contained array
does not have the specified number of elements, a std::out_of_range
is thrown.
If the specified element cannot be converted to T
(i.e., toml::get
fails), a toml::type_error
is thrown.
toml::find(value, keys...)
#
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* Equivalent to toml::get<T>(const value&) */ find(
const basic_value<TC>& v, const K1& k1, const K2& k2, const Ks& ... ks);
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* Equivalent to toml::get<T>(value&) */ find(
basic_value<TC>& v, const K1& k1, const K2& k2, const Ks& ... ks);
template<typename T, typename TC, typename K1, typename K2, typename ... Ks>
/* Equivalent to toml::get<T>(value&&) */ find(
basic_value<TC>&& v, const K1& k1, const K2& k2, const Ks& ... ks);
This function calls toml::find
recursively.
The failure conditions and the exceptions thrown are the same as those for toml::find
.
toml::find_or(value, key, fallback)
#
template<typename T, typename TC, typename Key>
T find_or(const basic_value<TC>& v, const Key& key, T&& opt);
The find_or
function takes a default value to avoid throwing an exception when the search fails.
The default value must be of the same type as the return type T
. Therefore, unlike toml::find<T>
, find_or
infers the type T
.
You can specify T
explicitly with find_or<T>
, but this always returns a new value. To obtain a reference, do not specify T
.
When T
is basic_value
#
template<typename TC, typename K>
basic_value<TC>& find_or(basic_value<TC>& v, const K& key, basic_value<TC>& opt) noexcept
template<typename TC, typename K>
basic_value<TC> const& find_or(const basic_value<TC>& v, const K& key, const basic_value<TC>& opt) noexcept
Searches for the corresponding value and returns it without conversion. Because no conversion is needed, a reference can be returned.
If the value is not found, the default value is returned.
When T
is toml::value::{some_type}
#
template<typename T, typename TC, typename K>
T& find_or(basic_value<TC>& v, const K& key, T& opt) noexcept
template<typename T, typename TC, typename K>
T const& find_or(const basic_value<TC>& v, const K& key, const T& opt) noexcept
Searches for the corresponding value and returns it without conversion. Because no conversion is needed, a reference can be returned.
If the value is not found or if a different type is stored, the default value is returned.
When T
is const char*
#
template<typename T, typename TC, typename K>
T find_or(const basic_value<TC>& v, const K& key, T opt)
Searches for the corresponding value and returns it as a std::string
.
Since the fallback is constructed from const char*
to std::string
, a reference cannot be returned in case of failure.
When T
is any other type
#
template<typename T, typename TC, typename K>
T find_or(const basic_value<TC>& v, const K& key, T opt);
Searches for the corresponding value and converts it to T
before returning it.
Because conversion is performed, a reference cannot be returned.
When multiple keys are provided #
template<typename Value, typename K1, typename K2, typename K3, typename ... Ks>
auto find_or(Value&& v, const K1& k1, const K2& k2, K3&& k3, Ks&& ... keys) noexcept
-> decltype(find_or(v, k2, std::forward<K3>(k3), std::forward<Ks>(keys)...))
Interprets the last element in the key sequence as the default value and applies find_or
recursively.
If the inferred type of T
is toml::value
or toml::value::some_type
, a reference can be returned.
If T
is explicitly specified, conversion is always performed.