#ifndef TOML11_FROM_TOML #define TOML11_FROM_TOML #include "value.hpp" namespace toml { template(), typename std::enable_if<(vT != toml::value_t::Unknown && vT != value_t::Empty), std::nullptr_t>::type = nullptr> void from_toml(T& x, const toml::value& v) { if(v.type() != vT) throw type_error("from_toml: value type: " + stringize(v.type()) + std::string(" is not arguemnt type: ") + stringize(vT)); x = v.cast(); return; } template(), typename std::enable_if<(vT == toml::value_t::Unknown) && (!toml::detail::is_map::value) && toml::detail::is_container::value, std::nullptr_t>::type = nullptr> void from_toml(T& x, const toml::value& v) { // TODO the case of x is not dynamic container case if(v.type() != value_t::Array) throw type_error("from_toml: value type: " + stringize(v.type()) + std::string(" is not argument type: Array")); const auto& ar = v.cast(); try { toml::resize(x, ar.size()); } catch(std::invalid_argument& iv) { throw toml::type_error("toml::from_toml: static array size is not enough"); } auto iter = x.begin(); for(const auto& val : ar) { typename T::value_type v; from_toml(v, val); *iter = std::move(v); ++iter; } return; } template(), typename std::enable_if<(vT == toml::value_t::Unknown) && toml::detail::is_map::value, std::nullptr_t>::type = nullptr> void from_toml(T& x, const toml::value& v) { if(v.type() != value_t::Table) throw type_error("from_toml: value type: " + stringize(v.type()) + std::string(" is not argument type: Table")); x.clear(); const auto& tb = v.cast(); for(const auto& kv : tb) { x.insert(kv); } return; } namespace detail { template constexpr toml::value_t determine_castable_type() { return check_type() != toml::value_t::Unknown ? check_type() : toml::detail::is_map::value ? toml::value_t::Table : toml::detail::is_container::value ? toml::value_t::Array : toml::value_t::Unknown; } template struct from_toml_tie_impl { constexpr static std::size_t index = sizeof...(Ts) - N; constexpr static toml::value_t type_index = determine_castable_type< typename std::tuple_element>::type>(); static void invoke(std::tuple tie, const toml::value& v) { if(type_index == v.type()) { from_toml(std::get(tie), v); return; } return from_toml_tie_impl::invoke(tie, v); } }; template struct from_toml_tie_impl<0, Ts...> { static void invoke(std::tuple tie, const toml::value& v) { throw type_error("from_toml(tie, value): no match"); } }; } // detail template void from_toml(std::tuple tie, const toml::value& v) { detail::from_toml_tie_impl::invoke(tie, v); return; } } // toml #endif // TOML11_FROM_TOML