mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 17:52:14 +08:00
fix: correctly resolve overloads of get_or
This commit is contained in:
@@ -55,11 +55,66 @@ BOOST_AUTO_TEST_CASE(test_get_or)
|
|||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v, "num", 0));
|
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v, "num", 0));
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v, "foo", 0));
|
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v, "foo", 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// requires conversion int -> uint
|
||||||
{
|
{
|
||||||
toml::value v1(42);
|
toml::value v1(42);
|
||||||
toml::value v2(3.14);
|
toml::value v2(3.14);
|
||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v1, 0));
|
BOOST_CHECK_EQUAL(42u, toml::get_or(v1, 0u));
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v2, 0));
|
BOOST_CHECK_EQUAL(0u, toml::get_or(v2, 0u));
|
||||||
|
}
|
||||||
|
|
||||||
|
// exact toml type
|
||||||
|
{
|
||||||
|
toml::value v1(42);
|
||||||
|
toml::value v2(3.14);
|
||||||
|
BOOST_CHECK_EQUAL(42, toml::get_or(v1, toml::integer(0)));
|
||||||
|
BOOST_CHECK_EQUAL(0, toml::get_or(v2, toml::integer(0)));
|
||||||
|
|
||||||
|
toml::value v3("foobar");
|
||||||
|
toml::string s("bazqux");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::get_or(v3, s));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::get_or(v1, s));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::string
|
||||||
|
{
|
||||||
|
toml::value v1("foobar");
|
||||||
|
toml::value v2(42);
|
||||||
|
|
||||||
|
std::string s1("bazqux");
|
||||||
|
const std::string s2("bazqux");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, s1));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, s1));
|
||||||
|
|
||||||
|
std::string& v1r = toml::get_or(v1, s1);
|
||||||
|
std::string& s1r = toml::get_or(v2, s1);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", v1r);
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", s1r);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, s2));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, s2));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, std::move(s1)));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, std::move(s1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// string literal
|
||||||
|
{
|
||||||
|
toml::value v1("foobar");
|
||||||
|
toml::value v2(42);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, "bazqux"));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, "bazqux"));
|
||||||
|
|
||||||
|
const char* lit = "bazqux";
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, lit));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, lit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
148
toml/get.hpp
148
toml/get.hpp
@@ -420,13 +420,14 @@ find(toml::value&& v, const toml::key& ky)
|
|||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// get_or
|
// get_or(value, fallback)
|
||||||
|
|
||||||
template<typename T>
|
// ----------------------------------------------------------------------------
|
||||||
decltype(::toml::get<typename std::remove_cv<
|
// specialization for the exact toml types (return type becomes lvalue ref)
|
||||||
typename std::remove_reference<T>::type>::type>(
|
|
||||||
std::declval<const toml::value&>()))
|
template<typename T, typename std::enable_if<
|
||||||
get_or(const toml::value& v, T&& opt)
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T const& get_or(const toml::value& v, const T& opt)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -435,14 +436,12 @@ get_or(const toml::value& v, T&& opt)
|
|||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
return std::forward<T>(opt);
|
return opt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T, typename std::enable_if<
|
||||||
decltype(::toml::get<typename std::remove_cv<
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
typename std::remove_reference<T>::type>::type>(
|
T& get_or(toml::value& v, T& opt)
|
||||||
std::declval<toml::value&>()))
|
|
||||||
get_or(toml::value& v, T&& opt)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -451,26 +450,135 @@ get_or(toml::value& v, T&& opt)
|
|||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
return std::forward<T>(opt);
|
return opt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T, typename std::enable_if<
|
||||||
decltype(::toml::get<typename std::remove_cv<
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
typename std::remove_reference<T>::type>::type>(
|
T&& get_or(toml::value&& v, T&& opt)
|
||||||
std::declval<toml::value&&>()))
|
|
||||||
get_or(toml::value&& v, T&& opt)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return get<typename std::remove_cv<
|
return get<typename std::remove_cv<
|
||||||
typename std::remove_reference<T>::type>::type>(std::move(v));
|
typename std::remove_reference<T>::type>::type>(v);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
return std::forward<T>(opt);
|
return opt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// specialization for std::string (return type becomes lvalue ref)
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string const& get_or(const toml::value& v, const T& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<std::string>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string& get_or(toml::value& v, T& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<std::string>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string get_or(toml::value&& v, T&& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<std::string>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_string_literal<typename std::remove_reference<T>::type>::value,
|
||||||
|
std::nullptr_t>::type = nullptr>
|
||||||
|
std::string get_or(const toml::value& v, T&& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<std::string>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return std::string(opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// others (require type conversion and return type cannot be lvalue reference)
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>,
|
||||||
|
detail::negation<std::is_same<T, std::string>>,
|
||||||
|
detail::negation<detail::is_string_literal<typename std::remove_reference<T>::type>>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T get_or(const toml::value& v, T&& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<typename std::remove_cv<
|
||||||
|
typename std::remove_reference<T>::type>::type>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>,
|
||||||
|
detail::negation<std::is_same<T, std::string>>,
|
||||||
|
detail::negation<detail::is_string_literal<typename std::remove_reference<T>::type>>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T get_or(toml::value& v, T&& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<typename std::remove_cv<
|
||||||
|
typename std::remove_reference<T>::type>::type>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>,
|
||||||
|
detail::negation<std::is_same<T, std::string>>,
|
||||||
|
detail::negation<detail::is_string_literal<typename std::remove_reference<T>::type>>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T get_or(toml::value&& v, T&& opt)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return get<typename std::remove_cv<
|
||||||
|
typename std::remove_reference<T>::type>::type>(v);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto get_or(const toml::table& tab, const toml::key& ky, T&& opt)
|
auto get_or(const toml::table& tab, const toml::key& ky, T&& opt)
|
||||||
|
Reference in New Issue
Block a user