diff --git a/toml/get.hpp b/toml/get.hpp index 0f5ff92..88ec0eb 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -189,62 +189,87 @@ get(const basic_value& v) } } -/* // ============================================================================ // forward declaration to use this recursively. ignore this and go ahead. -template, // T is container - detail::has_resize_method, // T::resize(N) works - detail::negation> // but not toml::array - >::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template class M, template class V> +enable_if_t, // T is container + detail::has_resize_method, // T::resize(N) works + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// array-like type with resize(N) method +template class M, template class V> +enable_if_t, // T is container detail::negation>, // no T::resize() exists - detail::negation> // not toml::array - >::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template, // T is map - detail::negation> // but not toml::table - >::value, std::nullptr_t>::type = nullptr> -T get(const toml::value& v); + detail::negation< // not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); -template>, // not a toml::value - detail::has_from_toml_method, // but has from_toml(toml::value) memfn - std::is_default_constructible // and default constructible - >::value, std::nullptr_t>::type = nullptr> -T get(const toml::value& v); +// std::pair +template class M, template class V> +enable_if_t::value, T> +get(const basic_value&); -template> // not a toml::value - >::value, std::nullptr_t>::type = nullptr, - std::size_t = sizeof(::toml::from) // and has from specialization - > -T get(const toml::value& v); +// std::tuple +template class M, template class V> +enable_if_t::value, T> +get(const basic_value&); + +// map-like classes +template class M, template class V> +enable_if_t, // T is map + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// T.from_toml(v) +template class M, template class V> +enable_if_t>>, + detail::has_from_toml_method, // but has from_toml(toml::value) + std::is_default_constructible // and default constructible + >::value, T> +get(const basic_value&); + +// toml::from::from_toml(v) +template class M, template class V, + std::size_t S = sizeof(::toml::into)> +T get(const basic_value&); // ============================================================================ // array-like types; most likely STL container, like std::vector, etc. -template, // T is container - detail::has_resize_method, // T::resize(N) works - detail::negation> // but not toml::array - >::value, std::nullptr_t>::type> -T get(const value& v) +template class M, template class V> +enable_if_t, // T is container + detail::has_resize_method, // T::resize(N) works + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { using value_type = typename T::value_type; - const auto& ar = v.cast(); - - T container; container.resize(ar.size()); + const auto& ar = v.template cast(); + T container; + container.resize(ar.size()); std::transform(ar.cbegin(), ar.cend(), container.begin(), [](const value& x){return ::toml::get(x);}); return container; @@ -253,15 +278,18 @@ T get(const value& v) // ============================================================================ // array-like types; but does not have resize(); most likely std::array. -template class M, template class V> +enable_if_t, // T is container detail::negation>, // no T::resize() exists - detail::negation> // not toml::array - >::value, std::nullptr_t>::type> -T get(const value& v) + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { using value_type = typename T::value_type; - const auto& ar = v.cast(); + const auto& ar = v.template cast(); T container; if(ar.size() != container.size()) @@ -280,14 +308,15 @@ T get(const value& v) // ============================================================================ // std::pair. -template::value, std::nullptr_t>::type> -T get(const value& v) +template class M, template class V> +enable_if_t::value, T> +get(const basic_value& v) { using first_type = typename T::first_type; using second_type = typename T::second_type; - const auto& ar = v.cast(); + const auto& ar = v.template cast(); if(ar.size() != 2) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -305,21 +334,20 @@ T get(const value& v) namespace detail { - -template -T get_tuple_impl(const toml::array& a, index_sequence) +template +T get_tuple_impl(const Array& a, index_sequence) { return std::make_tuple( ::toml::get::type>(a.at(I))...); } - } // detail -template::value, std::nullptr_t>::type> -T get(const value& v) +template class M, template class V> +enable_if_t::value, T> +get(const basic_value& v) { - const auto& ar = v.cast(); + const auto& ar = v.template cast(); if(ar.size() != std::tuple_size::value) { 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. -template, // T is map - detail::negation> // but not toml::table - >::value, std::nullptr_t>::type> -T get(const toml::value& v) +template class M, template class V> +enable_if_t, // T is map + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { using key_type = typename T::key_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 " "convertible from std::string."); T map; - for(const auto& kv : v.cast()) + for(const auto& kv : v.template cast()) { map[key_type(kv.first)] = ::toml::get(kv.second); } return map; } - // ============================================================================ // user-defined, but compatible types. -template>, // not a toml::value - detail::has_from_toml_method, // but has from_toml(toml::value) memfn - std::is_default_constructible // and default constructible - >::value, std::nullptr_t>::type> -T get(const toml::value& v) +template class M, template class V> +enable_if_t>>, + detail::has_from_toml_method, // but has from_toml(toml::value) memfn + std::is_default_constructible // and default constructible + >::value, T> +get(const basic_value& v) { T ud; ud.from_toml(v); return ud; } -template> // not a toml::value - >::value, std::nullptr_t>::type, std::size_t> // and has from -T get(const toml::value& v) +template class M, template class V, + std::size_t> +T get(const basic_value& v) { return ::toml::from::from_toml(v); } +/* // ============================================================================ // find and get