mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 09:08:08 +08:00
feat: update toml::get<T> for basic_value
This commit is contained in:
188
toml/get.hpp
188
toml/get.hpp
@@ -189,62 +189,87 @@ get(const basic_value<C, M, V>& v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// forward declaration to use this recursively. ignore this and go ahead.
|
// forward declaration to use this recursively. ignore this and go ahead.
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
// array-like type with resize(N) method
|
||||||
detail::is_container<T>, // T is container
|
template<typename T, typename C,
|
||||||
detail::has_resize_method<T>, // T::resize(N) works
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // but not toml::array
|
enable_if_t<detail::conjunction<
|
||||||
>::value, std::nullptr_t>::type = nullptr>
|
detail::is_container<T>, // T is container
|
||||||
T get(const value& v);
|
detail::has_resize_method<T>, // T::resize(N) works
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
detail::negation< // but not toml::array
|
||||||
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>
|
||||||
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>&);
|
||||||
|
|
||||||
|
// array-like type with resize(N) method
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
|
enable_if_t<detail::conjunction<
|
||||||
detail::is_container<T>, // T is container
|
detail::is_container<T>, // T is container
|
||||||
detail::negation<detail::has_resize_method<T>>, // no T::resize() exists
|
detail::negation<detail::has_resize_method<T>>, // no T::resize() exists
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // not toml::array
|
detail::negation< // not toml::array
|
||||||
>::value, std::nullptr_t>::type = nullptr>
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>
|
||||||
T get(const value& v);
|
>::value, T>
|
||||||
template<typename T, typename std::enable_if<
|
get(const basic_value<C, M, V>&);
|
||||||
detail::is_std_pair<T>::value, std::nullptr_t>::type = nullptr>
|
|
||||||
T get(const value& v);
|
|
||||||
template<typename T, typename std::enable_if<
|
|
||||||
detail::is_std_tuple<T>::value, std::nullptr_t>::type = nullptr>
|
|
||||||
T get(const value& v);
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
|
||||||
detail::is_map<T>, // T is map
|
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // but not toml::table
|
|
||||||
>::value, std::nullptr_t>::type = nullptr>
|
|
||||||
T get(const toml::value& v);
|
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
// std::pair<T1, T2>
|
||||||
detail::negation<detail::is_exact_toml_type<T>>, // not a toml::value
|
template<typename T, typename C,
|
||||||
detail::has_from_toml_method<T>, // but has from_toml(toml::value) memfn
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
std::is_default_constructible<T> // and default constructible
|
enable_if_t<detail::is_std_pair<T>::value, T>
|
||||||
>::value, std::nullptr_t>::type = nullptr>
|
get(const basic_value<C, M, V>&);
|
||||||
T get(const toml::value& v);
|
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
// std::tuple<T1, T2, ...>
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // not a toml::value
|
template<typename T, typename C,
|
||||||
>::value, std::nullptr_t>::type = nullptr,
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
std::size_t = sizeof(::toml::from<T>) // and has from<T> specialization
|
enable_if_t<detail::is_std_tuple<T>::value, T>
|
||||||
>
|
get(const basic_value<C, M, V>&);
|
||||||
T get(const toml::value& v);
|
|
||||||
|
// map-like classes
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
|
enable_if_t<detail::conjunction<
|
||||||
|
detail::is_map<T>, // T is map
|
||||||
|
detail::negation< // but not toml::array
|
||||||
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>
|
||||||
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>&);
|
||||||
|
|
||||||
|
// T.from_toml(v)
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
|
enable_if_t<detail::conjunction<
|
||||||
|
detail::negation< // not a toml::* type
|
||||||
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>,
|
||||||
|
detail::has_from_toml_method<T, C, M, V>, // but has from_toml(toml::value)
|
||||||
|
std::is_default_constructible<T> // and default constructible
|
||||||
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>&);
|
||||||
|
|
||||||
|
// toml::from<T>::from_toml(v)
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V,
|
||||||
|
std::size_t S = sizeof(::toml::into<T>)>
|
||||||
|
T get(const basic_value<C, M, V>&);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// array-like types; most likely STL container, like std::vector, etc.
|
// array-like types; most likely STL container, like std::vector, etc.
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
template<typename T, typename C,
|
||||||
detail::is_container<T>, // T is container
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
detail::has_resize_method<T>, // T::resize(N) works
|
enable_if_t<detail::conjunction<
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // but not toml::array
|
detail::is_container<T>, // T is container
|
||||||
>::value, std::nullptr_t>::type>
|
detail::has_resize_method<T>, // T::resize(N) works
|
||||||
T get(const value& v)
|
detail::negation< // but not toml::array
|
||||||
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>
|
||||||
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
using value_type = typename T::value_type;
|
using value_type = typename T::value_type;
|
||||||
const auto& ar = v.cast<value_t::Array>();
|
const auto& ar = v.template cast<value_t::array>();
|
||||||
|
T container;
|
||||||
T container; container.resize(ar.size());
|
container.resize(ar.size());
|
||||||
std::transform(ar.cbegin(), ar.cend(), container.begin(),
|
std::transform(ar.cbegin(), ar.cend(), container.begin(),
|
||||||
[](const value& x){return ::toml::get<value_type>(x);});
|
[](const value& x){return ::toml::get<value_type>(x);});
|
||||||
return container;
|
return container;
|
||||||
@@ -253,15 +278,18 @@ T get(const value& v)
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// array-like types; but does not have resize(); most likely std::array.
|
// array-like types; but does not have resize(); most likely std::array.
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
|
enable_if_t<detail::conjunction<
|
||||||
detail::is_container<T>, // T is container
|
detail::is_container<T>, // T is container
|
||||||
detail::negation<detail::has_resize_method<T>>, // no T::resize() exists
|
detail::negation<detail::has_resize_method<T>>, // no T::resize() exists
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // not toml::array
|
detail::negation< // but not toml::array
|
||||||
>::value, std::nullptr_t>::type>
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>
|
||||||
T get(const value& v)
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
using value_type = typename T::value_type;
|
using value_type = typename T::value_type;
|
||||||
const auto& ar = v.cast<value_t::Array>();
|
const auto& ar = v.template cast<value_t::array>();
|
||||||
|
|
||||||
T container;
|
T container;
|
||||||
if(ar.size() != container.size())
|
if(ar.size() != container.size())
|
||||||
@@ -280,14 +308,15 @@ T get(const value& v)
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// std::pair.
|
// std::pair.
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<
|
template<typename T, typename C,
|
||||||
detail::is_std_pair<T>::value, std::nullptr_t>::type>
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
T get(const value& v)
|
enable_if_t<detail::is_std_pair<T>::value, T>
|
||||||
|
get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
using first_type = typename T::first_type;
|
using first_type = typename T::first_type;
|
||||||
using second_type = typename T::second_type;
|
using second_type = typename T::second_type;
|
||||||
|
|
||||||
const auto& ar = v.cast<value_t::Array>();
|
const auto& ar = v.template cast<value_t::array>();
|
||||||
if(ar.size() != 2)
|
if(ar.size() != 2)
|
||||||
{
|
{
|
||||||
throw std::out_of_range(detail::format_underline(concat_to_string(
|
throw std::out_of_range(detail::format_underline(concat_to_string(
|
||||||
@@ -305,21 +334,20 @@ T get(const value& v)
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
template<typename T, typename Array, std::size_t ... I>
|
||||||
template<typename T, std::size_t ...I>
|
T get_tuple_impl(const Array& a, index_sequence<I...>)
|
||||||
T get_tuple_impl(const toml::array& a, index_sequence<I...>)
|
|
||||||
{
|
{
|
||||||
return std::make_tuple(
|
return std::make_tuple(
|
||||||
::toml::get<typename std::tuple_element<I, T>::type>(a.at(I))...);
|
::toml::get<typename std::tuple_element<I, T>::type>(a.at(I))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<
|
template<typename T, typename C,
|
||||||
detail::is_std_tuple<T>::value, std::nullptr_t>::type>
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
T get(const value& v)
|
enable_if_t<detail::is_std_tuple<T>::value, T>
|
||||||
|
get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
const auto& ar = v.cast<value_t::Array>();
|
const auto& ar = v.template cast<value_t::array>();
|
||||||
if(ar.size() != std::tuple_size<T>::value)
|
if(ar.size() != std::tuple_size<T>::value)
|
||||||
{
|
{
|
||||||
throw std::out_of_range(detail::format_underline(concat_to_string(
|
throw std::out_of_range(detail::format_underline(concat_to_string(
|
||||||
@@ -336,11 +364,14 @@ T get(const value& v)
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// map-like types; most likely STL map, like std::map or std::unordered_map.
|
// map-like types; most likely STL map, like std::map or std::unordered_map.
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
template<typename T, typename C,
|
||||||
detail::is_map<T>, // T is map
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // but not toml::table
|
enable_if_t<detail::conjunction<
|
||||||
>::value, std::nullptr_t>::type>
|
detail::is_map<T>, // T is map
|
||||||
T get(const toml::value& v)
|
detail::negation< // but not toml::array
|
||||||
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>
|
||||||
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
using key_type = typename T::key_type;
|
using key_type = typename T::key_type;
|
||||||
using mapped_type = typename T::mapped_type;
|
using mapped_type = typename T::mapped_type;
|
||||||
@@ -348,36 +379,39 @@ T get(const toml::value& v)
|
|||||||
"toml::get only supports map type of which key_type is "
|
"toml::get only supports map type of which key_type is "
|
||||||
"convertible from std::string.");
|
"convertible from std::string.");
|
||||||
T map;
|
T map;
|
||||||
for(const auto& kv : v.cast<value_t::Table>())
|
for(const auto& kv : v.template cast<value_t::table>())
|
||||||
{
|
{
|
||||||
map[key_type(kv.first)] = ::toml::get<mapped_type>(kv.second);
|
map[key_type(kv.first)] = ::toml::get<mapped_type>(kv.second);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// user-defined, but compatible types.
|
// user-defined, but compatible types.
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
template<typename T, typename C,
|
||||||
detail::negation<detail::is_exact_toml_type<T>>, // not a toml::value
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
detail::has_from_toml_method<T>, // but has from_toml(toml::value) memfn
|
enable_if_t<detail::conjunction<
|
||||||
std::is_default_constructible<T> // and default constructible
|
detail::negation< // not a toml::* type
|
||||||
>::value, std::nullptr_t>::type>
|
detail::is_exact_toml_type<T, basic_value<C, M, V>>>,
|
||||||
T get(const toml::value& v)
|
detail::has_from_toml_method<T, C, M, V>, // but has from_toml(toml::value) memfn
|
||||||
|
std::is_default_constructible<T> // and default constructible
|
||||||
|
>::value, T>
|
||||||
|
get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
T ud;
|
T ud;
|
||||||
ud.from_toml(v);
|
ud.from_toml(v);
|
||||||
return ud;
|
return ud;
|
||||||
}
|
}
|
||||||
template<typename T, typename std::enable_if<detail::conjunction<
|
template<typename T, typename C,
|
||||||
detail::negation<detail::is_exact_toml_type<T>> // not a toml::value
|
template<typename ...> class M, template<typename ...> class V,
|
||||||
>::value, std::nullptr_t>::type, std::size_t> // and has from<T>
|
std::size_t>
|
||||||
T get(const toml::value& v)
|
T get(const basic_value<C, M, V>& v)
|
||||||
{
|
{
|
||||||
return ::toml::from<T>::from_toml(v);
|
return ::toml::from<T>::from_toml(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// find and get
|
// find and get
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user