add from_toml(std::tie, value) and test for it

This commit is contained in:
ToruNiina
2017-04-20 16:13:06 +09:00
parent dccfcd99cf
commit f4afaa7509
2 changed files with 135 additions and 1 deletions

View File

@@ -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<int> ua;
std::map<std::string, toml::value> 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<toml::value_t::Boolean>(), true);
BOOST_CHECK_EQUAL(ut["val2"].cast<toml::value_t::Integer>(), 42);
BOOST_CHECK_CLOSE_FRACTION(ut["val3"].cast<toml::value_t::Float>(), 3.14, 1e-3);
BOOST_CHECK_EQUAL(ut["val4"].cast<toml::value_t::String >(), "piyo");
}

View File

@@ -30,6 +30,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <tuple>
#include <unordered_map> #include <unordered_map>
#include <chrono> #include <chrono>
#include <iomanip> #include <iomanip>
@@ -271,6 +272,38 @@ struct internal_error : public toml::exception
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
// template<typename intT, typename floatT>
// 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<typename T> template<typename T>
struct value_traits struct value_traits
{ {
@@ -867,6 +900,7 @@ to_toml(std::initializer_list<std::pair<std::string, toml::value>> init)
/* ------------------------------ from_toml --------------------------------- */ /* ------------------------------ from_toml --------------------------------- */
template<typename T, toml::value_t vT = toml::detail::check_type<T>(), template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
typename std::enable_if<(vT != toml::value_t::Unknown && typename std::enable_if<(vT != toml::value_t::Unknown &&
vT != value_t::Empty), std::nullptr_t>::type = nullptr> vT != value_t::Empty), std::nullptr_t>::type = nullptr>
@@ -916,6 +950,57 @@ void from_toml(T& x, const toml::value& v)
return; return;
} }
namespace detail
{
template<typename T>
constexpr toml::value_t determine_castable_type()
{
return check_type<T>() != toml::value_t::Unknown ? check_type<T>() :
toml::detail::is_map<T>::value ? toml::value_t::Table :
toml::detail::is_container<T>::value ? toml::value_t::Array :
toml::value_t::Unknown;
}
template<std::size_t N, typename ... Ts>
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<index, std::tuple<Ts...>>::type>();
static void invoke(std::tuple<Ts& ...> tie, const toml::value& v)
{
if(type_index == v.type())
{
from_toml(std::get<index>(tie), v);
return;
}
return from_toml_tie_impl<N-1, Ts...>::invoke(tie, v);
}
};
template<typename ... Ts>
struct from_toml_tie_impl<0, Ts...>
{
static void invoke(std::tuple<Ts& ...> tie, const toml::value& v)
{
throw type_error("from_toml(tie, value): no match");
}
};
} // detail
template<typename ... Ts>
void from_toml(std::tuple<Ts& ...> tie, const toml::value& v)
{
detail::from_toml_tie_impl<sizeof...(Ts), Ts...>::invoke(tie, v);
return;
}
/* ------------------------------ get --------------------------------- */
template<typename T, toml::value_t vT = toml::detail::check_type<T>(), template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
typename std::enable_if<(vT != toml::value_t::Unknown && typename std::enable_if<(vT != toml::value_t::Unknown &&
vT != value_t::Empty), std::nullptr_t>::type = nullptr> vT != value_t::Empty), std::nullptr_t>::type = nullptr>
@@ -951,6 +1036,5 @@ T get(const toml::value& v)
return tmp; return tmp;
} }
}// toml }// toml
#endif// TOML_FOR_MODERN_CPP #endif// TOML_FOR_MODERN_CPP