diff --git a/tests/test_from_toml.cpp b/tests/test_from_toml.cpp index 6db1ec7..7cf6698 100644 --- a/tests/test_from_toml.cpp +++ b/tests/test_from_toml.cpp @@ -131,3 +131,53 @@ BOOST_AUTO_TEST_CASE(test_from_toml_cast) } +BOOST_AUTO_TEST_CASE(test_from_toml_tie) +{ + toml::Boolean b(42); + toml::Integer i(42); + toml::Float f(3.14); + toml::Array a; + a.emplace_back(2); + a.emplace_back(7); + a.emplace_back(1); + a.emplace_back(8); + a.emplace_back(2); + toml::Table t; + t.emplace("val1", true); + t.emplace("val2", 42); + t.emplace("val3", 3.14); + t.emplace("val4", "piyo"); + + toml::value vb(b); + toml::value vi(i); + toml::value vf(f); + toml::value va(a); + toml::value vt(t); + + bool ub; + int ui; + float uf; + std::deque ua; + std::map ut; + + toml::from_toml(std::tie(ub, ui, uf, ua, ut), vb); + toml::from_toml(std::tie(ub, ui, uf, ua, ut), vi); + toml::from_toml(std::tie(ub, ui, uf, ua, ut), vf); + toml::from_toml(std::tie(ub, ui, uf, ua, ut), va); + toml::from_toml(std::tie(ub, ui, uf, ua, ut), va); + toml::from_toml(std::tie(ub, ui, uf, ua, ut), vt); + + BOOST_CHECK_EQUAL(ub, true); + BOOST_CHECK_EQUAL(ui, 42); + BOOST_CHECK_CLOSE_FRACTION(uf, 3.14, 1e-3); + BOOST_CHECK_EQUAL(ua.at(0), 2); + BOOST_CHECK_EQUAL(ua.at(1), 7); + BOOST_CHECK_EQUAL(ua.at(2), 1); + BOOST_CHECK_EQUAL(ua.at(3), 8); + BOOST_CHECK_EQUAL(ua.at(4), 2); + BOOST_CHECK_EQUAL(ut["val1"].cast(), true); + BOOST_CHECK_EQUAL(ut["val2"].cast(), 42); + BOOST_CHECK_CLOSE_FRACTION(ut["val3"].cast(), 3.14, 1e-3); + BOOST_CHECK_EQUAL(ut["val4"].cast(), "piyo"); +} + diff --git a/toml/toml.hpp b/toml/toml.hpp index 8835fbe..66dab9e 100644 --- a/toml/toml.hpp +++ b/toml/toml.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -271,6 +272,38 @@ struct internal_error : public toml::exception }; /* -------------------------------------------------------------------------- */ +// template +// struct basic_datetime +// { +// intT year; +// intT month; +// intT day; +// intT hour; +// intT minite; +// intT second; +// floatT subsecond; +// intT offset_hour; +// intT offset_minute; +// +// basic_datetime(intT y, intT m, intT d); +// basic_datetime(intT h, intT m, intT s, floatT ss); +// basic_datetime(intT y, intT mth, intT d, +// intT h, intT min, intT s, floatT ss); +// basic_datetime(intT y, intT mth, intT d, +// intT h, intT min, intT s, floatT ss, intT oh, intT om); +// +// basic_datetime(const std::chrono::system_clock::time_point& tp); +// basic_datetime(std::chrono::system_clock::time_point&& tp); +// +// operator std::chrono::system_clock::time_point() const; +// operator std::time_t() const; +// operator std::tm() const; +// +// private: +// void validate() +// }; + + template struct value_traits { @@ -867,6 +900,7 @@ to_toml(std::initializer_list> init) /* ------------------------------ from_toml --------------------------------- */ + template(), typename std::enable_if<(vT != toml::value_t::Unknown && vT != value_t::Empty), std::nullptr_t>::type = nullptr> @@ -916,6 +950,57 @@ void from_toml(T& x, const toml::value& v) 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; +} + +/* ------------------------------ get --------------------------------- */ + template(), typename std::enable_if<(vT != toml::value_t::Unknown && vT != value_t::Empty), std::nullptr_t>::type = nullptr> @@ -951,6 +1036,5 @@ T get(const toml::value& v) return tmp; } - }// toml #endif// TOML_FOR_MODERN_CPP